diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..232c2d00 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,37 @@ +--- +name: 'Issue report' +about: 'Create a report to help us improve the quality of our software' +title: '' +labels: '' +assignees: '' +--- + +**Caution** + +The Issues are strictly limited for the reporting of problem encountered with the software provided in this project. +For any other problem related to the STM32 product, the performance, the hardware characteristics and boards, the tools the environment in general, please post your report to the **ST Community** in the STM32 MCUs dedicated [page](https://community.st.com/s/topic/0TO0X000000BSqSWAW/stm32-mcus). + +**Describe the set-up** + + * The board (either ST RPN reference or your custom board) + * IDE or at least the compiler and its version + +**Describe the bug (skip if none)** + +A clear and concise description of what the bug is. + +**How to reproduce the bug (skip if none)** + +1. Indicate the global behavior of your application project +2. List the modules that you suspect to be the cause of the problem (Drivers, BSP, MW...) +3. Describe the use case that generates the problem +4. How we can reproduce the problem + + +**Additional context** + +If you have a first analysis, an enhancement, a fix or a patch, thank you to share your proposal. + +**Screenshots** + +If applicable, add screenshots to help explain your problem. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 52e0c56a..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve the quality of our software -title: '' -labels: '' -assignees: '' - ---- - -**Caution** -The Issues are strictly limited for the reporting of problem encountered with the software provided in this project. -For any other problem related to the STM32 product, the performance, the hardware characteristics and boards, the tools, or the environment in general, please post a topic in the [ST Community/STM32 MCUs forum](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus). - -**Describe the set-up** - * The board (either ST RPN reference or your custom board). - * IDE or at least the compiler and its version. - -**Describe the bug** -A clear and concise description of what the bug is. - -**How To Reproduce** -1. Indicate the global behavior of your application project. - -2. The modules that you suspect to be the cause of the problem (Driver, BSP, MW ...). - -3. The use case that generates the problem. - -4. How we can reproduce the problem. - - -**Additional context** -If you have a first analysis or patch correction, thank you to share your proposal. - -**Screenshots** -If applicable, add screenshots to help explain your problem. diff --git a/.github/ISSUE_TEMPLATE/other-issue.md b/.github/ISSUE_TEMPLATE/other-issue.md deleted file mode 100644 index 568a2d8e..00000000 --- a/.github/ISSUE_TEMPLATE/other-issue.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: 'Other Issue ' -about: Generic issue description -title: '' -labels: '' -assignees: '' - ---- - -**Caution** -The Issues are strictly limited for the reporting of problem encountered with the software provided in this project. -For any other problem related to the STM32 product, the performance, the hardware characteristics and boards, the tools, or the environment in general, please post a topic in the [ST Community/STM32 MCUs forum](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus). - -**Describe the set-up** - * The board (either ST RPN reference or your custom board). - * IDE or at least the compiler and its version. - -**Additional context** -If you have a first analysis or a patch proposal, thank you to share your proposal. - -**Screenshots** -If applicable, add screenshots to help explain your problem. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a95c94fd..5efc26c5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,11 +7,9 @@ This guide mainly focuses on steps to be followed to submit an issue or a pull-r ### 1. Before opening an issue -To report a bug or a request please file an issue in the right repository (example for [STM32CubeWL](https://github.com/STMicroelectronics/STM32CubeWL/issues/new/choose)). - Please check the following boxes before posting an issue: - [ ] `Make sure you are using the latest commit (major releases are tagged, but corrections are available as new commits).` -- [ ] `Make sure your issue is a question/feedback/suggestions RELATED TO the software provided in this repository.` Otherwise, it should be submitted to the ST Community under the MCU topic [page](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus). +- [ ] `Make sure your issue is a question/feedback/suggestions RELATED TO the software provided in this repository.` Otherwise, it should be submitted to the ST Community under the MCU topic [page](https://community.st.com/s/topic/0TO0X000000BSqSWAW/stm32-mcus). - [ ] `Make sure your issue is not already reported/fixed on GitHub or discussed on a previous issue.` Please refer to this [dashboard](https://github.com/orgs/STMicroelectronics/projects/2) for the list of issues and pull-requests. Do not forget to browse into the **closed** issues. ### 2. Posting the issue diff --git a/Documentation/STM32CubeWLGettingStarted.pdf b/Documentation/STM32CubeWLGettingStarted.pdf index 6079c5b7..5b1111bc 100644 Binary files a/Documentation/STM32CubeWLGettingStarted.pdf and b/Documentation/STM32CubeWLGettingStarted.pdf differ diff --git a/Drivers/BSP/STM32WLxx_Nucleo/LICENSE.md b/Drivers/BSP/STM32WLxx_Nucleo/LICENSE.md new file mode 100644 index 00000000..f6031ef2 --- /dev/null +++ b/Drivers/BSP/STM32WLxx_Nucleo/LICENSE.md @@ -0,0 +1,27 @@ +Copyright 2020(-2021) STMicroelectronics. +All rights reserved. + +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 the copyright holder 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. diff --git a/Drivers/BSP/STM32WLxx_Nucleo/License.md b/Drivers/BSP/STM32WLxx_Nucleo/License.md deleted file mode 100644 index c6b7c8bd..00000000 --- a/Drivers/BSP/STM32WLxx_Nucleo/License.md +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2020 STMicroelectronics - -This software component is licensed by STMicroelectronics under the **BSD-3-Clause** license. You may not use this software except in compliance with this license. You may obtain a copy of the license [here](https://opensource.org/licenses/BSD-3-Clause). \ No newline at end of file diff --git a/Drivers/BSP/STM32WLxx_Nucleo/Release_Notes.html b/Drivers/BSP/STM32WLxx_Nucleo/Release_Notes.html index 9b9e4565..ca9f5916 100644 --- a/Drivers/BSP/STM32WLxx_Nucleo/Release_Notes.html +++ b/Drivers/BSP/STM32WLxx_Nucleo/Release_Notes.html @@ -21,14 +21,12 @@
-

Release Notes for STM32WLxx_Nucleo

+

Release Notes for

+

STM32WLxx_Nucleo

Copyright © 2020 STMicroelectronics

-

License

-

This software component is licensed by ST under BSD 3-Clause license, the “License”; You may not use this component except in compliance with the License. You may obtain a copy of the License at:

-

https://opensource.org/licenses/BSD-3-Clause

Purpose

This driver provides a set of functions to manage:

-
Firewall-based isolation
+Firewall-based isolation
Firewall-based isolation


@@ -53,54 +48,70 @@

Purpose

  • MPU-based Secure Engine Isolation : The MPU-based Secure Engine isolation relies on the concept of privileged and unprivileged levels of software execution. The software must run in unprivileged level of execution by default (when SBSFU or the User Application is running), except for very specific actions like platform initialization or interrupt handling.
  • -
    MPU-based isolation
    +MPU-based isolation
    MPU-based isolation

    For more details, refer to UM2262, AppendixA : Getting started with X-CUBE-SBSFU expansion package

    -
    -

    Update History

    +
    +

    Update History

    - +

    Main Changes

      -
    • Add service to enable and disable IRQ services

    • -
    • Modify prepareimage to allow merge of any elf and bin files

    • +
    • STM32WB Series : Add specific CKS lock key service (cannot be called in BY-PASS mode)

    • +
    • Remove bootinfo structure and services

    • +
    • Locked objects are no more accessible by searches

    • +
    • Minor update with no functional impact

    Known Limitations

    None

    Backward Compatibility

    +

    Break of compatibility with V2.4.1

    +
    +
    +
    + +
    +

    Main Changes

    +
      +
    • Add service to enable and disable IRQ services

    • +
    • Modify prepareimage to allow merge of any elf and bin files

    • +
    +

    Known Limitations

    +

    None

    +

    Backward Compatibility

    No Break of compatibility with V2.4.0

    -

    Main Changes

    +

    Main Changes

    • Fix for IT management with firewall.

    • Minor update with no functional impact.

    -

    Known Limitations

    +

    Known Limitations

    None

    -

    Backward Compatibility

    +

    Backward Compatibility

    None

    -

    Main Changes

    +

    Main Changes

    • Management of interruption during code execution inside the firewall is now supported for applications with high real time constraints. IRQ are no more disabled when entering into the isolated code environment, when IT_MANAGEMENT compilation switch is enable.

    • -
    • Add multi-images support:

      +
    • Add multi-images support:
      • A maximum of 3 active images and 3 download areas can be configured.
      • Slot number parameter is added to the service SE_APPLI_GetActiveFwInfo().
      • Control for read/write/erase operations are extended to the 3 active images headers.
      • For each active image, authentication, decryption and integrity are controlled with specific keys.
    • -
    • Add image state handling feature:

      +
    • Add image state handling feature:
      • State information are added in the firmware header: FWIMG_STATE_NEW, FWIMG_STATE_SELFTEST, FWIMG_STATE_INVALID, FWIMG_STATE_VALID, FWIMG_STATE_VALID_ALL.
      • New services added: SE_IMG_GetActiveFwState(), SE_IMG_SetActiveFwState(), SE_APP_ValidateFw().
      • @@ -112,7 +123,7 @@

        Main Changes

      • FWIMG_STATE_SELFTEST -> FWIMG_STATE_VALID_ALL : the active image identified as MASTER will validate all new installed active images in a single operation.
    -
  • Update prepare image tools to support:

    +
  • Update prepare image tools to support:
    • New examples mapping configuration:
        @@ -129,21 +140,21 @@

        Main Changes

    • For CKS_ENABLED feature (P-NUCLEO-WB55.Nucleo): the lock of CM0 keys is now done during execution of SE_LOCK_RESTRICT_SERVICES just before jumping into user application.

    -

    Known Limitations

    +

    Known Limitations

    None

    -

    Backward Compatibility

    +

    Backward Compatibility

    Break of compatibility with V2.1.0

  • -

    Main Changes

    +

    Main Changes

    • Management of header not contiguous with firmware for external flash : when slot0 is mapped in external flash, header of slot0 must be contiguous to SBSFU area, in order to be protected by secure memory

    • New Secure Engine service (SECBOOT_ECCDSA_WITH_AES128_CTR_SHA256) for initialization of OTFDEC with symmetric keys ; AES CTR cryptographic scheme is required for external flash with OTFDEC variant

    • -
    • Update of prepareimage.py utility to support :
      -

      +
    • Update of prepareimage.py utility to support :
      +
      • partial image update
      • @@ -155,32 +166,32 @@

        Main Changes

    • Changes in management of exceptions for STM32 series supporting Flash ECC error (STM32L4, STM32G0, STM32G4, STM32H7 and STM32WB series) : fix on double ecc error management

    -

    Known Limitations

    +

    Known Limitations

    None

    -

    Backward Compatibility

    +

    Backward Compatibility

    Break of compatibility with V2.0.0

    -

    Main Changes

    +

    Main Changes

    General improvements (software counter measures) against software attacks and against basic hardware faults injection

    Secure Engine extended with Key Management Services, replacing former secure engine crypto services when KMS feature is enabled

    Add SE_IMG_Erase API to be able to erase slot #0 header: mandatory for NUCLEO-L073RZ (specific behavior of STM32L0 flash interface : writing instructions during erasing sequence)

    prepareimage.py utility updated to support :
    - partial image update
    - pairing keys, for communication with STSAFE-A100

    -

    Known Limitations

    +

    Known Limitations

    None

    -

    Backward Compatibility

    +

    Backward Compatibility

    Break of compatibility with V1.2.0

    -

    Main Changes

    +

    Main Changes

    prepareimage/key/translate_key scripts improvements :
    - Quicker execution timing.
    - Support of big elf in order to be able to flash SBSFU+ UserApp from IDE : refer to AN5056 for more details.
    @@ -191,14 +202,14 @@

    Main Changes

    Security controls added :
    - Check the mapping of the data given as parameters toSecure Engine services (SE_BufferCheck_SBSFU() /SE_BufferCheck_in_se_ram()).
    - Clean Secure Engine RAM data (SE_LL_CORE_Cleanup())when leaving SBSFU (SE_LockRestrictServices()).

    -

    Known Limitations

    +

    Known Limitations

    None

    -

    Main Changes

    +

    Main Changes

    Multiple crypto scheme implemented under compilation switch (se_crypto_config.h) :
    - SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM: symmetric crypto.
    - SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256(default config) : asymmetric crypto with encrypted (AES128-CBC)Firmware.
    @@ -210,24 +221,23 @@

    Main Changes

    - Windows executable version of the python scripts available : This is now the default tooling for pre/post build actions (so python not mandatory any more)

    Secure Engine now using its own stack inside protected area

    Files structure updated to provide more feature modularity and feature customization flexibility

    -

    Known Limitations

    +

    Known Limitations

    None

    -

    Main Changes

    +

    Main Changes

    First release

    -

    Known Limitations

    +

    Known Limitations

    None

    -
    +
    diff --git a/Middlewares/ST/STM32_Secure_Engine/_htmresc/favicon.png b/Middlewares/ST/STM32_Secure_Engine/_htmresc/favicon.png new file mode 100644 index 00000000..06713eec Binary files /dev/null and b/Middlewares/ST/STM32_Secure_Engine/_htmresc/favicon.png differ diff --git a/Middlewares/ST/STM32_Secure_Engine/_htmresc/mini-st.css b/Middlewares/ST/STM32_Secure_Engine/_htmresc/mini-st.css deleted file mode 100644 index eb41d56c..00000000 --- a/Middlewares/ST/STM32_Secure_Engine/_htmresc/mini-st.css +++ /dev/null @@ -1,1700 +0,0 @@ -@charset "UTF-8"; -/* - Flavor name: Default (mini-default) - Author: Angelos Chalaris (chalarangelo@gmail.com) - Maintainers: Angelos Chalaris - mini.css version: v3.0.0-alpha.3 -*/ -/* - Browsers resets and base typography. -*/ -/* Core module CSS variable definitions */ -:root { - --fore-color: #111; - --secondary-fore-color: #444; - --back-color: #f8f8f8; - --secondary-back-color: #f0f0f0; - --blockquote-color: #f57c00; - --pre-color: #1565c0; - --border-color: #aaa; - --secondary-border-color: #ddd; - --heading-ratio: 1.19; - --universal-margin: 0.5rem; - --universal-padding: 0.125rem; - --universal-border-radius: 0.125rem; - --a-link-color: #0277bd; - --a-visited-color: #01579b; } - -html { - font-size: 14px; } - -a, b, del, em, i, ins, q, span, strong, u { - font-size: 1em; } - -html, * { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif; - line-height: 1.4; - -webkit-text-size-adjust: 100%; } - -* { - font-size: 1rem; } - -body { - margin: 0; - color: var(--fore-color); - background: var(--back-color); } - -details { - display: block; } - -summary { - display: list-item; } - -abbr[title] { - border-bottom: none; - text-decoration: underline dotted; } - -input { - overflow: visible; } - -img { - max-width: 100%; - height: auto; } - -h1, h2, h3, h4, h5, h6 { - line-height: 1.2; - margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); - font-weight: 500; } - h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { - color: var(--secondary-fore-color); - display: block; - margin-top: -0.25rem; } - -h1 { - font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } - -h2 { - font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio); ); - background: var(--mark-back-color); - font-weight: 600; - padding: 0.1em 0.5em 0.2em 0.5em; - color: var(--mark-fore-color); } - -h3 { - font-size: calc(1rem * var(--heading-ratio)); - padding-left: calc(2 * var(--universal-margin)); - /* background: var(--border-color); */ - } - -h4 { - font-size: 1rem;); - padding-left: calc(4 * var(--universal-margin)); } - -h5 { - font-size: 1rem; } - -h6 { - font-size: calc(1rem / var(--heading-ratio)); } - -p { - margin: var(--universal-margin); } - -ol, ul { - margin: var(--universal-margin); - padding-left: calc(6 * var(--universal-margin)); } - -b, strong { - font-weight: 700; } - -hr { - box-sizing: content-box; - border: 0; - line-height: 1.25em; - margin: var(--universal-margin); - height: 0.0625rem; - background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } - -blockquote { - display: block; - position: relative; - font-style: italic; - color: var(--secondary-fore-color); - margin: var(--universal-margin); - padding: calc(3 * var(--universal-padding)); - border: 0.0625rem solid var(--secondary-border-color); - border-left: 0.375rem solid var(--blockquote-color); - border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } - blockquote:before { - position: absolute; - top: calc(0rem - var(--universal-padding)); - left: 0; - font-family: sans-serif; - font-size: 3rem; - font-weight: 700; - content: "\201c"; - color: var(--blockquote-color); } - blockquote[cite]:after { - font-style: normal; - font-size: 0.75em; - font-weight: 700; - content: "\a— " attr(cite); - white-space: pre; } - -code, kbd, pre, samp { - font-family: Menlo, Consolas, monospace; - font-size: 0.85em; } - -code { - background: var(--secondary-back-color); - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - -kbd { - background: var(--fore-color); - color: var(--back-color); - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - -pre { - overflow: auto; - background: var(--secondary-back-color); - padding: calc(1.5 * var(--universal-padding)); - margin: var(--universal-margin); - border: 0.0625rem solid var(--secondary-border-color); - border-left: 0.25rem solid var(--pre-color); - border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } - -sup, sub, code, kbd { - line-height: 0; - position: relative; - vertical-align: baseline; } - -small, sup, sub, figcaption { - font-size: 0.75em; } - -sup { - top: -0.5em; } - -sub { - bottom: -0.25em; } - -figure { - margin: var(--universal-margin); } - -figcaption { - color: var(--secondary-fore-color); } - -a { - text-decoration: none; } - a:link { - color: var(--a-link-color); } - a:visited { - color: var(--a-visited-color); } - a:hover, a:focus { - text-decoration: underline; } - -/* - Definitions for the grid system, cards and containers. -*/ -.container { - margin: 0 auto; - padding: 0 calc(1.5 * var(--universal-padding)); } - -.row { - box-sizing: border-box; - display: flex; - flex: 0 1 auto; - flex-flow: row wrap; } - -.col-sm, -[class^='col-sm-'], -[class^='col-sm-offset-'], -.row[class*='cols-sm-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - -.col-sm, -.row.cols-sm > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - -.col-sm-1, -.row.cols-sm-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - -.col-sm-offset-0 { - margin-left: 0; } - -.col-sm-2, -.row.cols-sm-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - -.col-sm-offset-1 { - margin-left: 8.3333333333%; } - -.col-sm-3, -.row.cols-sm-3 > * { - max-width: 25%; - flex-basis: 25%; } - -.col-sm-offset-2 { - margin-left: 16.6666666667%; } - -.col-sm-4, -.row.cols-sm-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - -.col-sm-offset-3 { - margin-left: 25%; } - -.col-sm-5, -.row.cols-sm-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - -.col-sm-offset-4 { - margin-left: 33.3333333333%; } - -.col-sm-6, -.row.cols-sm-6 > * { - max-width: 50%; - flex-basis: 50%; } - -.col-sm-offset-5 { - margin-left: 41.6666666667%; } - -.col-sm-7, -.row.cols-sm-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - -.col-sm-offset-6 { - margin-left: 50%; } - -.col-sm-8, -.row.cols-sm-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - -.col-sm-offset-7 { - margin-left: 58.3333333333%; } - -.col-sm-9, -.row.cols-sm-9 > * { - max-width: 75%; - flex-basis: 75%; } - -.col-sm-offset-8 { - margin-left: 66.6666666667%; } - -.col-sm-10, -.row.cols-sm-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - -.col-sm-offset-9 { - margin-left: 75%; } - -.col-sm-11, -.row.cols-sm-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - -.col-sm-offset-10 { - margin-left: 83.3333333333%; } - -.col-sm-12, -.row.cols-sm-12 > * { - max-width: 100%; - flex-basis: 100%; } - -.col-sm-offset-11 { - margin-left: 91.6666666667%; } - -.col-sm-normal { - order: initial; } - -.col-sm-first { - order: -999; } - -.col-sm-last { - order: 999; } - -@media screen and (min-width: 500px) { - .col-md, - [class^='col-md-'], - [class^='col-md-offset-'], - .row[class*='cols-md-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - - .col-md, - .row.cols-md > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - - .col-md-1, - .row.cols-md-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - - .col-md-offset-0 { - margin-left: 0; } - - .col-md-2, - .row.cols-md-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - - .col-md-offset-1 { - margin-left: 8.3333333333%; } - - .col-md-3, - .row.cols-md-3 > * { - max-width: 25%; - flex-basis: 25%; } - - .col-md-offset-2 { - margin-left: 16.6666666667%; } - - .col-md-4, - .row.cols-md-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - - .col-md-offset-3 { - margin-left: 25%; } - - .col-md-5, - .row.cols-md-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - - .col-md-offset-4 { - margin-left: 33.3333333333%; } - - .col-md-6, - .row.cols-md-6 > * { - max-width: 50%; - flex-basis: 50%; } - - .col-md-offset-5 { - margin-left: 41.6666666667%; } - - .col-md-7, - .row.cols-md-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - - .col-md-offset-6 { - margin-left: 50%; } - - .col-md-8, - .row.cols-md-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - - .col-md-offset-7 { - margin-left: 58.3333333333%; } - - .col-md-9, - .row.cols-md-9 > * { - max-width: 75%; - flex-basis: 75%; } - - .col-md-offset-8 { - margin-left: 66.6666666667%; } - - .col-md-10, - .row.cols-md-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - - .col-md-offset-9 { - margin-left: 75%; } - - .col-md-11, - .row.cols-md-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - - .col-md-offset-10 { - margin-left: 83.3333333333%; } - - .col-md-12, - .row.cols-md-12 > * { - max-width: 100%; - flex-basis: 100%; } - - .col-md-offset-11 { - margin-left: 91.6666666667%; } - - .col-md-normal { - order: initial; } - - .col-md-first { - order: -999; } - - .col-md-last { - order: 999; } } -@media screen and (min-width: 1280px) { - .col-lg, - [class^='col-lg-'], - [class^='col-lg-offset-'], - .row[class*='cols-lg-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - - .col-lg, - .row.cols-lg > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - - .col-lg-1, - .row.cols-lg-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - - .col-lg-offset-0 { - margin-left: 0; } - - .col-lg-2, - .row.cols-lg-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - - .col-lg-offset-1 { - margin-left: 8.3333333333%; } - - .col-lg-3, - .row.cols-lg-3 > * { - max-width: 25%; - flex-basis: 25%; } - - .col-lg-offset-2 { - margin-left: 16.6666666667%; } - - .col-lg-4, - .row.cols-lg-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - - .col-lg-offset-3 { - margin-left: 25%; } - - .col-lg-5, - .row.cols-lg-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - - .col-lg-offset-4 { - margin-left: 33.3333333333%; } - - .col-lg-6, - .row.cols-lg-6 > * { - max-width: 50%; - flex-basis: 50%; } - - .col-lg-offset-5 { - margin-left: 41.6666666667%; } - - .col-lg-7, - .row.cols-lg-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - - .col-lg-offset-6 { - margin-left: 50%; } - - .col-lg-8, - .row.cols-lg-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - - .col-lg-offset-7 { - margin-left: 58.3333333333%; } - - .col-lg-9, - .row.cols-lg-9 > * { - max-width: 75%; - flex-basis: 75%; } - - .col-lg-offset-8 { - margin-left: 66.6666666667%; } - - .col-lg-10, - .row.cols-lg-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - - .col-lg-offset-9 { - margin-left: 75%; } - - .col-lg-11, - .row.cols-lg-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - - .col-lg-offset-10 { - margin-left: 83.3333333333%; } - - .col-lg-12, - .row.cols-lg-12 > * { - max-width: 100%; - flex-basis: 100%; } - - .col-lg-offset-11 { - margin-left: 91.6666666667%; } - - .col-lg-normal { - order: initial; } - - .col-lg-first { - order: -999; } - - .col-lg-last { - order: 999; } } -/* Card component CSS variable definitions */ -:root { - --card-back-color: #f8f8f8; - --card-fore-color: #111; - --card-border-color: #ddd; } - -.card { - display: flex; - flex-direction: column; - justify-content: space-between; - align-self: center; - position: relative; - width: 100%; - background: var(--card-back-color); - color: var(--card-fore-color); - border: 0.0625rem solid var(--card-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); - overflow: hidden; } - @media screen and (min-width: 320px) { - .card { - max-width: 320px; } } - .card > .sectione { - background: var(--card-back-color); - color: var(--card-fore-color); - box-sizing: border-box; - margin: 0; - border: 0; - border-radius: 0; - border-bottom: 0.0625rem solid var(--card-border-color); - padding: var(--universal-padding); - width: 100%; } - .card > .sectione.media { - height: 200px; - padding: 0; - -o-object-fit: cover; - object-fit: cover; } - .card > .sectione:last-child { - border-bottom: 0; } - -/* - Custom elements for card elements. -*/ -@media screen and (min-width: 240px) { - .card.small { - max-width: 240px; } } -@media screen and (min-width: 480px) { - .card.large { - max-width: 480px; } } -.card.fluid { - max-width: 100%; - width: auto; } - -.card.warning { -/* --card-back-color: #ffca28; */ - --card-back-color: #e5b8b7; - --card-border-color: #e8b825; } - -.card.error { - --card-back-color: #b71c1c; - --card-fore-color: #f8f8f8; - --card-border-color: #a71a1a; } - -.card > .sectione.dark { - --card-back-color: #e0e0e0; } - -.card > .sectione.double-padded { - padding: calc(1.5 * var(--universal-padding)); } - -/* - Definitions for forms and input elements. -*/ -/* Input_control module CSS variable definitions */ -:root { - --form-back-color: #f0f0f0; - --form-fore-color: #111; - --form-border-color: #ddd; - --input-back-color: #f8f8f8; - --input-fore-color: #111; - --input-border-color: #ddd; - --input-focus-color: #0288d1; - --input-invalid-color: #d32f2f; - --button-back-color: #e2e2e2; - --button-hover-back-color: #dcdcdc; - --button-fore-color: #212121; - --button-border-color: transparent; - --button-hover-border-color: transparent; - --button-group-border-color: rgba(124, 124, 124, 0.54); } - -form { - background: var(--form-back-color); - color: var(--form-fore-color); - border: 0.0625rem solid var(--form-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); - padding: calc(2 * var(--universal-padding)) var(--universal-padding); } - -fieldset { - border: 0.0625rem solid var(--form-border-color); - border-radius: var(--universal-border-radius); - margin: calc(var(--universal-margin) / 4); - padding: var(--universal-padding); } - -legend { - box-sizing: border-box; - display: table; - max-width: 100%; - white-space: normal; - font-weight: 700; - padding: calc(var(--universal-padding) / 2); } - -label { - padding: calc(var(--universal-padding) / 2) var(--universal-padding); } - -.input-group { - display: inline-block; } - .input-group.fluid { - display: flex; - align-items: center; - justify-content: center; } - .input-group.fluid > input { - max-width: 100%; - flex-grow: 1; - flex-basis: 0px; } - @media screen and (max-width: 499px) { - .input-group.fluid { - align-items: stretch; - flex-direction: column; } } - .input-group.vertical { - display: flex; - align-items: stretch; - flex-direction: column; } - .input-group.vertical > input { - max-width: 100%; - flex-grow: 1; - flex-basis: 0px; } - -[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; } - -[type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; } - -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; } - -input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], -[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { - box-sizing: border-box; - background: var(--input-back-color); - color: var(--input-fore-color); - border: 0.0625rem solid var(--input-border-color); - border-radius: var(--universal-border-radius); - margin: calc(var(--universal-margin) / 2); - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } - -input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { - border-color: var(--input-focus-color); - box-shadow: none; } -input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { - border-color: var(--input-invalid-color); - box-shadow: none; } -input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { - background: var(--secondary-back-color); } - -select { - max-width: 100%; } - -option { - overflow: hidden; - text-overflow: ellipsis; } - -[type="checkbox"], [type="radio"] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - position: relative; - height: calc(1rem + var(--universal-padding) / 2); - width: calc(1rem + var(--universal-padding) / 2); - vertical-align: text-bottom; - padding: 0; - flex-basis: calc(1rem + var(--universal-padding) / 2) !important; - flex-grow: 0 !important; } - [type="checkbox"]:checked:before, [type="radio"]:checked:before { - position: absolute; } - -[type="checkbox"]:checked:before { - content: '\2713'; - font-family: sans-serif; - font-size: calc(1rem + var(--universal-padding) / 2); - top: calc(0rem - var(--universal-padding)); - left: calc(var(--universal-padding) / 4); } - -[type="radio"] { - border-radius: 100%; } - [type="radio"]:checked:before { - border-radius: 100%; - content: ''; - top: calc(0.0625rem + var(--universal-padding) / 2); - left: calc(0.0625rem + var(--universal-padding) / 2); - background: var(--input-fore-color); - width: 0.5rem; - height: 0.5rem; } - -:placeholder-shown { - color: var(--input-fore-color); } - -::-ms-placeholder { - color: var(--input-fore-color); - opacity: 0.54; } - -button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; } - -button, html [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; } - -button { - overflow: visible; - text-transform: none; } - -button, [type="button"], [type="submit"], [type="reset"], -a.button, label.button, .button, -a[role="button"], label[role="button"], [role="button"] { - display: inline-block; - background: var(--button-back-color); - color: var(--button-fore-color); - border: 0.0625rem solid var(--button-border-color); - border-radius: var(--universal-border-radius); - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); - margin: var(--universal-margin); - text-decoration: none; - cursor: pointer; - transition: background 0.3s; } - button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, - a.button:hover, - a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, - a[role="button"]:hover, - a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { - background: var(--button-hover-back-color); - border-color: var(--button-hover-border-color); } - -input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { - cursor: not-allowed; - opacity: 0.75; } - -.button-group { - display: flex; - border: 0.0625rem solid var(--button-group-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); } - .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { - margin: 0; - max-width: 100%; - flex: 1 1 auto; - text-align: center; - border: 0; - border-radius: 0; - box-shadow: none; } - .button-group > :not(:first-child) { - border-left: 0.0625rem solid var(--button-group-border-color); } - @media screen and (max-width: 499px) { - .button-group { - flex-direction: column; } - .button-group > :not(:first-child) { - border: 0; - border-top: 0.0625rem solid var(--button-group-border-color); } } - -/* - Custom elements for forms and input elements. -*/ -button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { - --button-back-color: #1976d2; - --button-fore-color: #f8f8f8; } - button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { - --button-hover-back-color: #1565c0; } - -button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { - --button-back-color: #d32f2f; - --button-fore-color: #f8f8f8; } - button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { - --button-hover-back-color: #c62828; } - -button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { - --button-back-color: #308732; - --button-fore-color: #f8f8f8; } - button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { - --button-hover-back-color: #277529; } - -button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { - --button-back-color: #212121; - --button-fore-color: #f8f8f8; } - button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { - --button-hover-back-color: #111; } - -button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { - padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); - margin: var(--universal-margin); } - -button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { - padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); - margin: var(--universal-margin); } - -/* - Definitions for navigation elements. -*/ -/* Navigation module CSS variable definitions */ -:root { - --header-back-color: #f8f8f8; - --header-hover-back-color: #f0f0f0; - --header-fore-color: #444; - --header-border-color: #ddd; - --nav-back-color: #f8f8f8; - --nav-hover-back-color: #f0f0f0; - --nav-fore-color: #444; - --nav-border-color: #ddd; - --nav-link-color: #0277bd; - --footer-fore-color: #444; - --footer-back-color: #f8f8f8; - --footer-border-color: #ddd; - --footer-link-color: #0277bd; - --drawer-back-color: #f8f8f8; - --drawer-hover-back-color: #f0f0f0; - --drawer-border-color: #ddd; - --drawer-close-color: #444; } - -header { - height: 3.1875rem; - background: var(--header-back-color); - color: var(--header-fore-color); - border-bottom: 0.0625rem solid var(--header-border-color); - padding: calc(var(--universal-padding) / 4) 0; - white-space: nowrap; - overflow-x: auto; - overflow-y: hidden; } - header.row { - box-sizing: content-box; } - header .logo { - color: var(--header-fore-color); - font-size: 1.75rem; - padding: var(--universal-padding) calc(2 * var(--universal-padding)); - text-decoration: none; } - header button, header [type="button"], header .button, header [role="button"] { - box-sizing: border-box; - position: relative; - top: calc(0rem - var(--universal-padding) / 4); - height: calc(3.1875rem + var(--universal-padding) / 2); - background: var(--header-back-color); - line-height: calc(3.1875rem - var(--universal-padding) * 1.5); - text-align: center; - color: var(--header-fore-color); - border: 0; - border-radius: 0; - margin: 0; - text-transform: uppercase; } - header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { - background: var(--header-hover-back-color); } - -nav { - background: var(--nav-back-color); - color: var(--nav-fore-color); - border: 0.0625rem solid var(--nav-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); } - nav * { - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } - nav a, nav a:visited { - display: block; - color: var(--nav-link-color); - border-radius: var(--universal-border-radius); - transition: background 0.3s; } - nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { - text-decoration: none; - background: var(--nav-hover-back-color); } - nav .sublink-1 { - position: relative; - margin-left: calc(2 * var(--universal-padding)); } - nav .sublink-1:before { - position: absolute; - left: calc(var(--universal-padding) - 1 * var(--universal-padding)); - top: -0.0625rem; - content: ''; - height: 100%; - border: 0.0625rem solid var(--nav-border-color); - border-left: 0; } - nav .sublink-2 { - position: relative; - margin-left: calc(4 * var(--universal-padding)); } - nav .sublink-2:before { - position: absolute; - left: calc(var(--universal-padding) - 3 * var(--universal-padding)); - top: -0.0625rem; - content: ''; - height: 100%; - border: 0.0625rem solid var(--nav-border-color); - border-left: 0; } - -footer { - background: var(--footer-back-color); - color: var(--footer-fore-color); - border-top: 0.0625rem solid var(--footer-border-color); - padding: calc(2 * var(--universal-padding)) var(--universal-padding); - font-size: 0.875rem; } - footer a, footer a:visited { - color: var(--footer-link-color); } - -header.sticky { - position: -webkit-sticky; - position: sticky; - z-index: 1101; - top: 0; } - -footer.sticky { - position: -webkit-sticky; - position: sticky; - z-index: 1101; - bottom: 0; } - -.drawer-toggle:before { - display: inline-block; - position: relative; - vertical-align: bottom; - content: '\00a0\2261\00a0'; - font-family: sans-serif; - font-size: 1.5em; } -@media screen and (min-width: 500px) { - .drawer-toggle:not(.persistent) { - display: none; } } - -[type="checkbox"].drawer { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - [type="checkbox"].drawer + * { - display: block; - box-sizing: border-box; - position: fixed; - top: 0; - width: 320px; - height: 100vh; - overflow-y: auto; - background: var(--drawer-back-color); - border: 0.0625rem solid var(--drawer-border-color); - border-radius: 0; - margin: 0; - z-index: 1110; - right: -320px; - transition: right 0.3s; } - [type="checkbox"].drawer + * .drawer-close { - position: absolute; - top: var(--universal-margin); - right: var(--universal-margin); - z-index: 1111; - width: 2rem; - height: 2rem; - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - margin: 0; - cursor: pointer; - transition: background 0.3s; } - [type="checkbox"].drawer + * .drawer-close:before { - display: block; - content: '\00D7'; - color: var(--drawer-close-color); - position: relative; - font-family: sans-serif; - font-size: 2rem; - line-height: 1; - text-align: center; } - [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { - background: var(--drawer-hover-back-color); } - @media screen and (max-width: 320px) { - [type="checkbox"].drawer + * { - width: 100%; } } - [type="checkbox"].drawer:checked + * { - right: 0; } - @media screen and (min-width: 500px) { - [type="checkbox"].drawer:not(.persistent) + * { - position: static; - height: 100%; - z-index: 1100; } - [type="checkbox"].drawer:not(.persistent) + * .drawer-close { - display: none; } } - -/* - Definitions for the responsive table component. -*/ -/* Table module CSS variable definitions. */ -:root { - --table-border-color: #aaa; - --table-border-separator-color: #666; - --table-head-back-color: #e6e6e6; - --table-head-fore-color: #111; - --table-body-back-color: #f8f8f8; - --table-body-fore-color: #111; - --table-body-alt-back-color: #eee; } - -table { - border-collapse: separate; - border-spacing: 0; - : margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); - display: flex; - flex: 0 1 auto; - flex-flow: row wrap; - padding: var(--universal-padding); - padding-top: 0; - margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); } - table caption { - font-size: 1.25 * rem; - margin: calc(2 * var(--universal-margin)) 0; - max-width: 100%; - flex: 0 0 100%; - text-align: left;} - table thead, table tbody { - display: flex; - flex-flow: row wrap; - border: 0.0625rem solid var(--table-border-color); } - table thead { - z-index: 999; - border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; - border-bottom: 0.0625rem solid var(--table-border-separator-color); } - table tbody { - border-top: 0; - margin-top: calc(0 - var(--universal-margin)); - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - table tr { - display: flex; - padding: 0; } - table th, table td { - padding: calc(0.5 * var(--universal-padding)); - font-size: 0.9rem; } - table th { - text-align: left; - background: var(--table-head-back-color); - color: var(--table-head-fore-color); } - table td { - background: var(--table-body-back-color); - color: var(--table-body-fore-color); - border-top: 0.0625rem solid var(--table-border-color); } - -table:not(.horizontal) { - overflow: auto; - max-height: 850px; } - table:not(.horizontal) thead, table:not(.horizontal) tbody { - max-width: 100%; - flex: 0 0 100%; } - table:not(.horizontal) tr { - flex-flow: row wrap; - flex: 0 0 100%; } - table:not(.horizontal) th, table:not(.horizontal) td { - flex: 1 0 0%; - overflow: hidden; - text-overflow: ellipsis; } - table:not(.horizontal) thead { - position: sticky; - top: 0; } - table:not(.horizontal) tbody tr:first-child td { - border-top: 0; } - -table.horizontal { - border: 0; } - table.horizontal thead, table.horizontal tbody { - border: 0; - flex-flow: row nowrap; } - table.horizontal tbody { - overflow: auto; - justify-content: space-between; - flex: 1 0 0; - margin-left: calc( 4 * var(--universal-margin)); - padding-bottom: calc(var(--universal-padding) / 4); } - table.horizontal tr { - flex-direction: column; - flex: 1 0 auto; } - table.horizontal th, table.horizontal td { - width: 100%; - border: 0; - border-bottom: 0.0625rem solid var(--table-border-color); } - table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { - border-top: 0; } - table.horizontal th { - text-align: right; - border-left: 0.0625rem solid var(--table-border-color); - border-right: 0.0625rem solid var(--table-border-separator-color); } - table.horizontal thead tr:first-child { - padding-left: 0; } - table.horizontal th:first-child, table.horizontal td:first-child { - border-top: 0.0625rem solid var(--table-border-color); } - table.horizontal tbody tr:last-child td { - border-right: 0.0625rem solid var(--table-border-color); } - table.horizontal tbody tr:last-child td:first-child { - border-top-right-radius: 0.25rem; } - table.horizontal tbody tr:last-child td:last-child { - border-bottom-right-radius: 0.25rem; } - table.horizontal thead tr:first-child th:first-child { - border-top-left-radius: 0.25rem; } - table.horizontal thead tr:first-child th:last-child { - border-bottom-left-radius: 0.25rem; } - -@media screen and (max-width: 499px) { - table, table.horizontal { - border-collapse: collapse; - border: 0; - width: 100%; - display: table; } - table thead, table th, table.horizontal thead, table.horizontal th { - border: 0; - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - table tbody, table.horizontal tbody { - border: 0; - display: table-row-group; } - table tr, table.horizontal tr { - display: block; - border: 0.0625rem solid var(--table-border-color); - border-radius: var(--universal-border-radius); - background: #fafafa; - padding: var(--universal-padding); - margin: var(--universal-margin); - margin-bottom: calc(2 * var(--universal-margin)); } - table th, table td, table.horizontal th, table.horizontal td { - width: auto; } - table td, table.horizontal td { - display: block; - border: 0; - text-align: right; } - table td:before, table.horizontal td:before { - content: attr(data-label); - float: left; - font-weight: 600; } - table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { - border-top: 0; } - table tbody tr:last-child td, table.horizontal tbody tr:last-child td { - border-right: 0; } } -:root { - --table-body-alt-back-color: #eee; } - -table tr:nth-of-type(2n) > td { - background: var(--table-body-alt-back-color); } - -@media screen and (max-width: 500px) { - table tr:nth-of-type(2n) { - background: var(--table-body-alt-back-color); } } -:root { - --table-body-hover-back-color: #90caf9; } - -table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { - background: var(--table-body-hover-back-color); } - -@media screen and (max-width: 500px) { - table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { - background: var(--table-body-hover-back-color); } } -/* - Definitions for contextual background elements, toasts and tooltips. -*/ -/* Contextual module CSS variable definitions */ -:root { - --mark-back-color: #0277bd; - --mark-fore-color: #fafafa; } - -mark { - background: var(--mark-back-color); - color: var(--mark-fore-color); - font-size: 0.95em; - line-height: 1em; - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - mark.inline-block { - display: inline-block; - font-size: 1em; - line-height: 1.5; - padding: calc(var(--universal-padding) / 2) var(--universal-padding); } - -:root { - --toast-back-color: #424242; - --toast-fore-color: #fafafa; } - -.toast { - position: fixed; - bottom: calc(var(--universal-margin) * 3); - left: 50%; - transform: translate(-50%, -50%); - z-index: 1111; - color: var(--toast-fore-color); - background: var(--toast-back-color); - border-radius: calc(var(--universal-border-radius) * 16); - padding: var(--universal-padding) calc(var(--universal-padding) * 3); } - -:root { - --tooltip-back-color: #212121; - --tooltip-fore-color: #fafafa; } - -.tooltip { - position: relative; - display: inline-block; } - .tooltip:before, .tooltip:after { - position: absolute; - opacity: 0; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); - transition: all 0.3s; - z-index: 1010; - left: 50%; } - .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { - bottom: 75%; } - .tooltip.bottom:before, .tooltip.bottom:after { - top: 75%; } - .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { - opacity: 1; - clip: auto; - -webkit-clip-path: inset(0%); - clip-path: inset(0%); } - .tooltip:before { - content: ''; - background: transparent; - border: var(--universal-margin) solid transparent; - left: calc(50% - var(--universal-margin)); } - .tooltip:not(.bottom):before { - border-top-color: #212121; } - .tooltip.bottom:before { - border-bottom-color: #212121; } - .tooltip:after { - content: attr(aria-label); - color: var(--tooltip-fore-color); - background: var(--tooltip-back-color); - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - white-space: nowrap; - transform: translateX(-50%); } - .tooltip:not(.bottom):after { - margin-bottom: calc(2 * var(--universal-margin)); } - .tooltip.bottom:after { - margin-top: calc(2 * var(--universal-margin)); } - -:root { - --modal-overlay-color: rgba(0, 0, 0, 0.45); - --modal-close-color: #444; - --modal-close-hover-color: #f0f0f0; } - -[type="checkbox"].modal { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - [type="checkbox"].modal + div { - position: fixed; - top: 0; - left: 0; - display: none; - width: 100vw; - height: 100vh; - background: var(--modal-overlay-color); } - [type="checkbox"].modal + div .card { - margin: 0 auto; - max-height: 50vh; - overflow: auto; } - [type="checkbox"].modal + div .card .modal-close { - position: absolute; - top: 0; - right: 0; - width: 1.75rem; - height: 1.75rem; - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - margin: 0; - cursor: pointer; - transition: background 0.3s; } - [type="checkbox"].modal + div .card .modal-close:before { - display: block; - content: '\00D7'; - color: var(--modal-close-color); - position: relative; - font-family: sans-serif; - font-size: 1.75rem; - line-height: 1; - text-align: center; } - [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { - background: var(--modal-close-hover-color); } - [type="checkbox"].modal:checked + div { - display: flex; - flex: 0 1 auto; - z-index: 1200; } - [type="checkbox"].modal:checked + div .card .modal-close { - z-index: 1211; } - -:root { - --collapse-label-back-color: #e8e8e8; - --collapse-label-fore-color: #212121; - --collapse-label-hover-back-color: #f0f0f0; - --collapse-selected-label-back-color: #ececec; - --collapse-border-color: #ddd; - --collapse-content-back-color: #fafafa; - --collapse-selected-label-border-color: #0277bd; } - -.collapse { - width: calc(100% - 2 * var(--universal-margin)); - opacity: 1; - display: flex; - flex-direction: column; - margin: var(--universal-margin); - border-radius: var(--universal-border-radius); } - .collapse > [type="radio"], .collapse > [type="checkbox"] { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - .collapse > label { - flex-grow: 1; - display: inline-block; - height: 1.5rem; - cursor: pointer; - transition: background 0.3s; - color: var(--collapse-label-fore-color); - background: var(--collapse-label-back-color); - border: 0.0625rem solid var(--collapse-border-color); - padding: calc(1.5 * var(--universal-padding)); } - .collapse > label:hover, .collapse > label:focus { - background: var(--collapse-label-hover-back-color); } - .collapse > label + div { - flex-basis: auto; - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); - transition: max-height 0.3s; - max-height: 1px; } - .collapse > :checked + label { - background: var(--collapse-selected-label-back-color); - border-bottom-color: var(--collapse-selected-label-border-color); } - .collapse > :checked + label + div { - box-sizing: border-box; - position: relative; - width: 100%; - height: auto; - overflow: auto; - margin: 0; - background: var(--collapse-content-back-color); - border: 0.0625rem solid var(--collapse-border-color); - border-top: 0; - padding: var(--universal-padding); - clip: auto; - -webkit-clip-path: inset(0%); - clip-path: inset(0%); - max-height: 850px; } - .collapse > label:not(:first-of-type) { - border-top: 0; } - .collapse > label:first-of-type { - border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } - .collapse > label:last-of-type:not(:first-of-type) { - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - .collapse > label:last-of-type:first-of-type { - border-radius: var(--universal-border-radius); } - .collapse > :checked:last-of-type:not(:first-of-type) + label { - border-radius: 0; } - .collapse > :checked:last-of-type + label + div { - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - -/* - Custom elements for contextual background elements, toasts and tooltips. -*/ -mark.secondary { - --mark-back-color: #d32f2f; } - -mark.tertiary { - --mark-back-color: #308732; } - -mark.tag { - padding: calc(var(--universal-padding)/2) var(--universal-padding); - border-radius: 1em; } - -/* - Definitions for progress elements and spinners. -*/ -/* Progress module CSS variable definitions */ -:root { - --progress-back-color: #ddd; - --progress-fore-color: #555; } - -progress { - display: block; - vertical-align: baseline; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - height: 0.75rem; - width: calc(100% - 2 * var(--universal-margin)); - margin: var(--universal-margin); - border: 0; - border-radius: calc(2 * var(--universal-border-radius)); - background: var(--progress-back-color); - color: var(--progress-fore-color); } - progress::-webkit-progress-value { - background: var(--progress-fore-color); - border-top-left-radius: calc(2 * var(--universal-border-radius)); - border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } - progress::-webkit-progress-bar { - background: var(--progress-back-color); } - progress::-moz-progress-bar { - background: var(--progress-fore-color); - border-top-left-radius: calc(2 * var(--universal-border-radius)); - border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } - progress[value="1000"]::-webkit-progress-value { - border-radius: calc(2 * var(--universal-border-radius)); } - progress[value="1000"]::-moz-progress-bar { - border-radius: calc(2 * var(--universal-border-radius)); } - progress.inline { - display: inline-block; - vertical-align: middle; - width: 60%; } - -:root { - --spinner-back-color: #ddd; - --spinner-fore-color: #555; } - -@keyframes spinner-donut-anim { - 0% { - transform: rotate(0deg); } - 100% { - transform: rotate(360deg); } } -.spinner { - display: inline-block; - margin: var(--universal-margin); - border: 0.25rem solid var(--spinner-back-color); - border-left: 0.25rem solid var(--spinner-fore-color); - border-radius: 50%; - width: 1.25rem; - height: 1.25rem; - animation: spinner-donut-anim 1.2s linear infinite; } - -/* - Custom elements for progress bars and spinners. -*/ -progress.primary { - --progress-fore-color: #1976d2; } - -progress.secondary { - --progress-fore-color: #d32f2f; } - -progress.tertiary { - --progress-fore-color: #308732; } - -.spinner.primary { - --spinner-fore-color: #1976d2; } - -.spinner.secondary { - --spinner-fore-color: #d32f2f; } - -.spinner.tertiary { - --spinner-fore-color: #308732; } - -/* - Definitions for icons - powered by Feather (https://feathericons.com/). -*/ -span[class^='icon-'] { - display: inline-block; - height: 1em; - width: 1em; - vertical-align: -0.125em; - background-size: contain; - margin: 0 calc(var(--universal-margin) / 4); } - span[class^='icon-'].secondary { - -webkit-filter: invert(25%); - filter: invert(25%); } - span[class^='icon-'].inverse { - -webkit-filter: invert(100%); - filter: invert(100%); } - -span.icon-alert { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-bookmark { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-calendar { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-credit { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-edit { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } -span.icon-link { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-help { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-home { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } -span.icon-info { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-lock { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-mail { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } -span.icon-location { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } -span.icon-phone { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-rss { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } -span.icon-search { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-settings { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-share { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-cart { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-upload { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-user { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } - -/* - Definitions for utilities and helper classes. -*/ -/* Utility module CSS variable definitions */ -:root { - --generic-border-color: rgba(0, 0, 0, 0.3); - --generic-box-shadow: 0 0.25rem 0.25rem 0 rgba(0, 0, 0, 0.125), 0 0.125rem 0.125rem -0.125rem rgba(0, 0, 0, 0.25); } - -.hidden { - display: none !important; } - -.visually-hidden { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } - -.bordered { - border: 0.0625rem solid var(--generic-border-color) !important; } - -.rounded { - border-radius: var(--universal-border-radius) !important; } - -.circular { - border-radius: 50% !important; } - -.shadowed { - box-shadow: var(--generic-box-shadow) !important; } - -.responsive-margin { - margin: calc(var(--universal-margin) / 4) !important; } - @media screen and (min-width: 500px) { - .responsive-margin { - margin: calc(var(--universal-margin) / 2) !important; } } - @media screen and (min-width: 1280px) { - .responsive-margin { - margin: var(--universal-margin) !important; } } - -.responsive-padding { - padding: calc(var(--universal-padding) / 4) !important; } - @media screen and (min-width: 500px) { - .responsive-padding { - padding: calc(var(--universal-padding) / 2) !important; } } - @media screen and (min-width: 1280px) { - .responsive-padding { - padding: var(--universal-padding) !important; } } - -@media screen and (max-width: 499px) { - .hidden-sm { - display: none !important; } } -@media screen and (min-width: 500px) and (max-width: 1279px) { - .hidden-md { - display: none !important; } } -@media screen and (min-width: 1280px) { - .hidden-lg { - display: none !important; } } -@media screen and (max-width: 499px) { - .visually-hidden-sm { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } -@media screen and (min-width: 500px) and (max-width: 1279px) { - .visually-hidden-md { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } -@media screen and (min-width: 1280px) { - .visually-hidden-lg { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } - -/*# sourceMappingURL=mini-default.css.map */ diff --git a/Middlewares/ST/STM32_Secure_Engine/_htmresc/mini-st_2020.css b/Middlewares/ST/STM32_Secure_Engine/_htmresc/mini-st_2020.css new file mode 100644 index 00000000..986f4d42 --- /dev/null +++ b/Middlewares/ST/STM32_Secure_Engine/_htmresc/mini-st_2020.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/Middlewares/ST/STM32_Secure_Engine/_htmresc/st_logo.png b/Middlewares/ST/STM32_Secure_Engine/_htmresc/st_logo.png deleted file mode 100644 index 8b80057f..00000000 Binary files a/Middlewares/ST/STM32_Secure_Engine/_htmresc/st_logo.png and /dev/null differ diff --git a/Middlewares/ST/STM32_Secure_Engine/_htmresc/st_logo_2020.png b/Middlewares/ST/STM32_Secure_Engine/_htmresc/st_logo_2020.png new file mode 100644 index 00000000..d6cebb5a Binary files /dev/null and b/Middlewares/ST/STM32_Secure_Engine/_htmresc/st_logo_2020.png differ diff --git a/Middlewares/Third_Party/LoRaWAN/Conf/Commissioning_template.h b/Middlewares/Third_Party/LoRaWAN/Conf/Commissioning_template.h index efc12164..3b399304 100644 --- a/Middlewares/Third_Party/LoRaWAN/Conf/Commissioning_template.h +++ b/Middlewares/Third_Party/LoRaWAN/Conf/Commissioning_template.h @@ -26,13 +26,11 @@ * @brief End-device commissioning parameters ****************************************************************************** */ + /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __COMMISSIONING_H__ #define __COMMISSIONING_H__ -#ifdef __cplusplus -extern "C" { -#endif /*! ****************************************************************************** ********************************** WARNING *********************************** @@ -81,8 +79,4 @@ extern "C" { /* USER CODE END EC2 */ -#ifdef __cplusplus -} -#endif - #endif /* __COMMISSIONING_H__ */ diff --git a/Middlewares/Third_Party/LoRaWAN/Conf/frag_decoder_if_template.h b/Middlewares/Third_Party/LoRaWAN/Conf/frag_decoder_if_template.h new file mode 100644 index 00000000..4c1eae05 --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/Conf/frag_decoder_if_template.h @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * @file frag_decoder_if_template.h + * @author MCD Application Team + * @brief Applicative interfaces of LoRa-Alliance fragmentation decoder + ****************************************************************************** + * @attention + * + *

    © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

    + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FRAG_DECODER_IF_H__ +#define __FRAG_DECODER_IF_H__ + +#ifdef __cplusplus +extern "C" { +#endif +/* Includes ------------------------------------------------------------------*/ +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ + +#define INTEROP_TEST_MODE 0 + +#if (INTEROP_TEST_MODE == 1) +/*! + * Maximum number of fragment that can be handled. + * + * \remark This parameter has an impact on the memory footprint. + */ +#define FRAG_MAX_NB 20 + +/*! + * Maximum fragment size that can be handled. + * + * \remark This parameter has an impact on the memory footprint. + */ +#define FRAG_MAX_SIZE 50 + +/*! + * Maximum number of extra frames that can be handled. + * + * \remark This parameter has an impact on the memory footprint. + */ +#define FRAG_MAX_REDUNDANCY 5 + +#else /* INTEROP_TEST_MODE == 0 */ +/*! + * Maximum number of fragment that can be handled. + * + * \remark This parameter has an impact on the memory footprint. + * \note FRAG_MAX_NB = (SLOT_DWL_1_END - SLOT_DWL_1_START) / FRAG_MAX_SIZE + */ +#define FRAG_MAX_NB 716 + +/*! + * Maximum fragment size that can be handled. + * + * \remark This parameter has an impact on the memory footprint. + */ +#define FRAG_MAX_SIZE 120 + +/*! + * Maximum number of extra frames that can be handled. + * + * \remark This parameter has an impact on the memory footprint. + * \note FRAG_MAX_NB * 0.10 (with redundancy = 10 %) + */ +#define FRAG_MAX_REDUNDANCY 72 + +#endif /* INTEROP_TEST_MODE */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Functions Definition ------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __FRAG_DECODER_IF_H__ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/LoRaWAN/Conf/lora_info_template.c b/Middlewares/Third_Party/LoRaWAN/Conf/lora_info_template.c index 52d1aa8d..c82825a9 100644 --- a/Middlewares/Third_Party/LoRaWAN/Conf/lora_info_template.c +++ b/Middlewares/Third_Party/LoRaWAN/Conf/lora_info_template.c @@ -20,6 +20,7 @@ /* Includes ------------------------------------------------------------------*/ #include "LoRaMac.h" #include "lora_info.h" +#include "sys_app.h" /* APP_PRINTF */ /* USER CODE BEGIN Includes */ @@ -118,7 +119,7 @@ void LoraInfo_Init(void) loraInfo.ActivationMode = 3; #else /* LORAWAN_KMS == 1 */ loraInfo.Kms = 1; - loraInfo.ActivationMode = ACTIVATION_BY_PERSONALISATION + OVER_THE_AIR_ACTIVATION << 1; + loraInfo.ActivationMode = ACTIVATION_BY_PERSONALIZATION + (OVER_THE_AIR_ACTIVATION << 1); #endif /* LORAWAN_KMS */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Conf/lorawan_conf_template.h b/Middlewares/Third_Party/LoRaWAN/Conf/lorawan_conf_template.h index ce94762f..7e14a134 100644 --- a/Middlewares/Third_Party/LoRaWAN/Conf/lorawan_conf_template.h +++ b/Middlewares/Third_Party/LoRaWAN/Conf/lorawan_conf_template.h @@ -25,8 +25,6 @@ extern "C" { #endif /* Includes ------------------------------------------------------------------*/ -#include "stm32_systime.h" -#include "sys_app.h" /* needed for APP_PRINTF */ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ @@ -40,7 +38,7 @@ extern "C" { /* Region ------------------------------------*/ /* the region listed here will be linked in the MW code */ -/* the applic (on sys_conf.h) shall just configure one region at the time */ +/* the application (on sys_conf.h) shall just configure one region at the time */ /*#define REGION_AS923*/ /*#define REGION_AU915*/ /*#define REGION_CN470*/ @@ -52,9 +50,24 @@ extern "C" { #define REGION_US915 /*#define REGION_RU864*/ -#define HYBRID_ENABLED 0 +/** + * \brief Limits the number usable channels by default for AU915, CN470 and US915 regions + * \note the default channel mask with this option activates the first 8 channels. \ + * this default mask can be modified in the RegionXXXXXInitDefaults function associated with the active region. + */ +#define HYBRID_ENABLED 0 + +/** + * \brief Define the read access of the keys in memory + * \note this value should be disabled after the development process + */ +#define KEY_EXTRACTABLE 1 -#define KEY_LOG_ENABLED 1 +/*! + * Enables/Disables the context storage management storage. + * Must be enabled for LoRaWAN 1.0.4 or later. + */ +#define CONTEXT_MANAGEMENT_ENABLED 0 /* Class B ------------------------------------*/ #define LORAMAC_CLASSB_ENABLED 0 @@ -113,4 +126,5 @@ extern "C" { #endif #endif /* __LORAWAN_CONF_H__ */ + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/LoRaWAN/Conf/se-identity_template.h b/Middlewares/Third_Party/LoRaWAN/Conf/se-identity_template.h index 8ed42876..da87d282 100644 --- a/Middlewares/Third_Party/LoRaWAN/Conf/se-identity_template.h +++ b/Middlewares/Third_Party/LoRaWAN/Conf/se-identity_template.h @@ -28,7 +28,7 @@ * * Portions COPYRIGHT 2020 STMicroelectronics * - * @file se-identity_template.c + * @file se-identity_template.h * @author MCD Application Team * @brief Secure Element identity and keys ****************************************************************************** diff --git a/Middlewares/Third_Party/LoRaWAN/Crypto/soft-se.c b/Middlewares/Third_Party/LoRaWAN/Crypto/soft-se.c index a1d81d6e..a7c2b12b 100644 --- a/Middlewares/Third_Party/LoRaWAN/Crypto/soft-se.c +++ b/Middlewares/Third_Party/LoRaWAN/Crypto/soft-se.c @@ -1,35 +1,29 @@ /*! - * \file soft-se.c - * - * \brief Secure Element software implementation - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2020 Semtech - * - * ___ _____ _ ___ _ _____ ___ ___ ___ ___ - * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| - * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| - * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| - * embedded.connectivity.solutions=============== - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - * - * \author Gregory Cristian ( Semtech ) - * - * \author Daniel Jaeckle ( STACKFORCE ) - * - * \author Johannes Bruder ( STACKFORCE ) - */ + * \file soft-se.c + * + * \brief Secure Element software implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2020 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + */ + /** ****************************************************************************** * @@ -48,37 +42,21 @@ #include "lorawan_conf.h" /* LORAWAN_KMS */ #include "radio.h" /* needed for Random */ #include "utilities.h" -#include "LoRaMacHeaderTypes.h" -#include "secure-element.h" -#include "se-identity.h" - +#include "mw_log_conf.h" /* needed for MW_LOG */ #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) #include "lorawan_aes.h" #include "cmac.h" #else /* LORAWAN_KMS == 1 */ -#include "mw_log_conf.h" /* needed for MW_LOG */ #include "kms_if.h" #endif /* LORAWAN_KMS */ -/* Private constants ---------------------------------------------------------*/ -/*! - * Number of supported crypto keys - */ -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) -#if ( LORAMAC_MAX_MC_CTX == 1 ) -#define NUM_OF_KEYS 14UL -#else /* LORAMAC_MAX_MC_CTX > 1 */ -#define NUM_OF_KEYS 23UL -#endif /* LORAMAC_MAX_MC_CTX */ +#include "LoRaMacHeaderTypes.h" -#else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ -#if ( LORAMAC_MAX_MC_CTX == 1 ) -#define NUM_OF_KEYS 10UL -#else /* LORAMAC_MAX_MC_CTX > 1 */ -#define NUM_OF_KEYS 19UL -#endif /* LORAMAC_MAX_MC_CTX */ -#endif /* USE_LRWAN_1_1_X_CRYPTO */ +#include "secure-element.h" +#include "secure-element-nvm.h" +#include "se-identity.h" +/* Private constants ---------------------------------------------------------*/ /*! * MIC computation offset * \remark required for 1.1.x support @@ -103,95 +81,17 @@ */ #define HEX16(X) HEX8(X), X[8], X[9], X[10], X[11], X[12], X[13], X[14], X[15] -#if defined (KEY_LOG_ENABLED) && (KEY_LOG_ENABLED == 1) -#define KEY_LOG(TS,VL,...) do{ {UTIL_ADV_TRACE_COND_FSend(VL, T_REG_OFF, TS, __VA_ARGS__);} }while(0); -#else /* !KEY_LOG_ENABLED */ -#define KEY_LOG(TS,VL,...) -#endif /* KEY_LOG_ENABLED */ /* Private Types ---------------------------------------------------------*/ - -/*! - * Identifier value pair type for Keys - */ -typedef struct sKey -{ - /* - * Key identifier - */ - KeyIdentifier_t KeyID; - -#if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - /* - * Key value - */ - uint8_t KeyValue[SE_KEY_SIZE]; -#else /* LORAWAN_KMS == 1 */ - /* - * Key object index in the above list - */ - CK_OBJECT_HANDLE Object_Index; -#endif /* LORAWAN_KMS */ -} Key_t; - -/* - * Secure Element Non Volatile Context structure - */ -typedef struct sSecureElementNvCtx -{ - /* - * DevEUI storage - */ - uint8_t DevEui[SE_EUI_SIZE]; - /* - * Join EUI storage - */ - uint8_t JoinEui[SE_EUI_SIZE]; - /* - * Key List - */ - Key_t KeyList[NUM_OF_KEYS]; -} SecureElementNvCtx_t; - /* Private variables ---------------------------------------------------------*/ /*! * Secure element context */ -static SecureElementNvCtx_t SeNvmCtx = -{ - /*! - * end-device IEEE EUI (big endian) - * - * \remark In this application the value is automatically generated by calling - * BoardGetUniqueId function - */ - .DevEui = LORAWAN_DEVICE_EUI, - /*! - * App/Join server IEEE EUI (big endian) - */ - .JoinEui = LORAWAN_JOIN_EUI -}; - -#if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) -static const Key_t InitialKeyList[NUM_OF_KEYS] = SOFT_SE_KEY_LIST; -#endif /* LORAWAN_KMS == 0 */ - -static SecureElementNvmEvent SeNvmCtxChanged; +static SecureElementNvmData_t* SeNvm; #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) #else /* LORAWAN_KMS == 1 */ -static CK_ULONG DeriveKey_template_class = CKO_SECRET_KEY; -static CK_ULONG DeriveKey_template_destroyable = CK_TRUE; -static CK_ULONG DeriveKey_template_encrypt = CK_TRUE; -static CK_ULONG DeriveKey_template_decrypt = CK_TRUE; -static CK_ULONG DeriveKey_template_extract = CK_FALSE; -static CK_ATTRIBUTE DeriveKey_template[] = -{ - {CKA_CLASS, (CK_VOID_PTR) &DeriveKey_template_class, sizeof(CK_ULONG)}, - {CKA_DESTROYABLE, (CK_VOID_PTR) &DeriveKey_template_destroyable, sizeof(CK_ULONG)}, - {CKA_ENCRYPT, (CK_VOID_PTR) &DeriveKey_template_encrypt, sizeof(CK_ULONG)}, - {CKA_DECRYPT, (CK_VOID_PTR) &DeriveKey_template_decrypt, sizeof(CK_ULONG)}, - {CKA_EXTRACTABLE, (CK_VOID_PTR) &DeriveKey_template_extract, sizeof(CK_ULONG)} -}; +/* WARNING: Should be modified at the end of product development */ +static const CK_ULONG GlobalTemplateLabel = 0x444E524CU; /* * Intermediate buffer used for two reasons: @@ -199,22 +99,82 @@ static CK_ATTRIBUTE DeriveKey_template[] = * - for Cmac combine InitVector + input buff */ static uint8_t input_align_combined_buf[PAYLOAD_MAX_SIZE + SE_KEY_SIZE] ALIGN(4); + static uint8_t output_align[PAYLOAD_MAX_SIZE] ALIGN(4); + static uint8_t tag[SE_KEY_SIZE] ALIGN(4) = {0}; #endif /* LORAWAN_KMS */ /* Private functions prototypes ---------------------------------------------------*/ #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) -static SecureElementStatus_t GetKeyByID(KeyIdentifier_t keyID, Key_t **keyItem); +static SecureElementStatus_t GetKeyByID( KeyIdentifier_t keyID, Key_t **keyItem ); #else /* LORAWAN_KMS == 1 */ -static SecureElementStatus_t GetKeyIndexByID(KeyIdentifier_t keyID, CK_OBJECT_HANDLE *keyItem); +static SecureElementStatus_t GetKeyIndexByID( KeyIdentifier_t keyID, CK_OBJECT_HANDLE *keyIndex ); + +static SecureElementStatus_t GetSpecificLabelByID( KeyIdentifier_t keyID, uint32_t *specificLabel ); + +static SecureElementStatus_t DeleteAllDynamicKeys( void ); #endif /* LORAWAN_KMS */ +#if (defined (KEY_EXTRACTABLE) && (KEY_EXTRACTABLE == 1)) +static void PrintKey( KeyIdentifier_t key ); +#endif /* KEY_EXTRACTABLE */ + static SecureElementStatus_t ComputeCmac(uint8_t *micBxBuffer, uint8_t *buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t *cmac); -static void DummyCB(void); + /* Private functions ---------------------------------------------------------*/ +#if (defined (KEY_EXTRACTABLE) && (KEY_EXTRACTABLE == 1)) +static void PrintKey( KeyIdentifier_t key ) +{ + SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; + Key_t *keyItem; + retval = SecureElementGetKeyByID(key, &keyItem); + if (retval == SECURE_ELEMENT_SUCCESS) + { + if (key == APP_KEY) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### AppKey: "); + } + else if (key == NWK_KEY) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### NwkKey: "); + } + else if (key == APP_S_KEY) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### AppSKey: "); + } + else if (key == NWK_S_KEY) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### NwkSKey: "); + } + else if (key == MC_ROOT_KEY) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### MCRootKey: "); + } + else if (key == MC_KE_KEY) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### MCKEKey: "); + } + else if (key == MC_KEY_0) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### MCKey_0: "); + } + else if (key == MC_APP_S_KEY_0) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### MCAppSKey_0: "); + } + else if (key == MC_NWK_S_KEY_0) + { + MW_LOG(TS_OFF, VLEVEL_M, "###### MCNwkSKey_0: "); + } + MW_LOG(TS_OFF, VLEVEL_M, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", + HEX16(keyItem->KeyValue)); + } +} +#endif /* KEY_EXTRACTABLE */ + #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) /* * Gets key item from key list. @@ -223,17 +183,17 @@ static void DummyCB(void); * \param[OUT] keyItem - Key item reference * \retval - Status of the operation */ -static SecureElementStatus_t GetKeyByID(KeyIdentifier_t keyID, Key_t **keyItem) +static SecureElementStatus_t GetKeyByID( KeyIdentifier_t keyID, Key_t** keyItem ) { - for (uint8_t i = 0; i < NUM_OF_KEYS; i++) - { - if (SeNvmCtx.KeyList[i].KeyID == keyID) + for( uint8_t i = 0; i < NUM_OF_KEYS; i++ ) { - *keyItem = &(SeNvmCtx.KeyList[i]); - return SECURE_ELEMENT_SUCCESS; + if( SeNvm->KeyList[i].KeyID == keyID ) + { + *keyItem = &( SeNvm->KeyList[i] ); + return SECURE_ELEMENT_SUCCESS; + } } - } - return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; } #else /* LORAWAN_KMS == 1 */ @@ -241,32 +201,165 @@ static SecureElementStatus_t GetKeyByID(KeyIdentifier_t keyID, Key_t **keyItem) /* * Gets key Index from key list in KMS table * - * \param[IN] keyID - Key identifier - * \param[OUT] keyIndex - Key item reference - * \retval - Status of the operation + * \param[IN] keyID - Key identifier + * \param[OUT] keyIndex - Key item reference + * \retval - Status of the operation */ -static SecureElementStatus_t GetKeyIndexByID(KeyIdentifier_t keyID, CK_OBJECT_HANDLE *keyIndex) +static SecureElementStatus_t GetKeyIndexByID( KeyIdentifier_t keyID, CK_OBJECT_HANDLE *keyIndex ) { - for (uint8_t i = 0; i < NUM_OF_KEYS; i++) - { - if (SeNvmCtx.KeyList[i].KeyID == keyID) + for (uint8_t i = 0; i < NUM_OF_KEYS; i++) { - *keyIndex = SeNvmCtx.KeyList[i].Object_Index; - return SECURE_ELEMENT_SUCCESS; + if (SeNvm->KeyList[i].KeyID == keyID) + { + *keyIndex = SeNvm->KeyList[i].Object_Index; + return SECURE_ELEMENT_SUCCESS; + } } - } - return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; } -#endif /* LORAWAN_KMS */ +static SecureElementStatus_t GetSpecificLabelByID( KeyIdentifier_t keyID, uint32_t *specificLabel ) +{ + SecureElementStatus_t retval = SECURE_ELEMENT_SUCCESS; + switch (keyID) + { + case APP_KEY: + *specificLabel = 0x5F505041U; + break; + case NWK_KEY: + *specificLabel = 0x5F4B574EU; + break; +#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) + case J_S_INT_KEY: + *specificLabel = 0x314B574EU; + break; + case J_S_ENC_KEY: + *specificLabel = 0x324B574EU; + break; + case F_NWK_S_INT_KEY: + *specificLabel = 0x334B574EU; + break; + case S_NWK_S_INT_KEY: + *specificLabel = 0x344B574EU; + break; + case NWK_S_ENC_KEY: + *specificLabel = 0x354B574EU; + break; +#else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ + case NWK_S_KEY: + *specificLabel = 0x534B574EU; + break; +#endif /* USE_LRWAN_1_1_X_CRYPTO */ + case APP_S_KEY: + *specificLabel = 0x53505041U; + break; + case MC_ROOT_KEY: + *specificLabel = 0x5452434DU; + break; + case MC_KE_KEY: + *specificLabel = 0x454B434DU; + break; + case MC_KEY_0: + *specificLabel = 0x304B434DU; + break; + case MC_APP_S_KEY_0: + *specificLabel = 0x3053414DU; + break; + case MC_NWK_S_KEY_0: + *specificLabel = 0x30534E4DU; + break; +#if ( LORAMAC_MAX_MC_CTX > 1 ) + case MC_KEY_1: + *specificLabel = 0x314B434DU; + break; + case MC_APP_S_KEY_1: + *specificLabel = 0x3153414DU; + break; + case MC_NWK_S_KEY_1: + *specificLabel = 0x31534E4DU; + break; + case MC_KEY_2: + *specificLabel = 0x324B434DU; + break; + case MC_APP_S_KEY_2: + *specificLabel = 0x3253414DU; + break; + case MC_NWK_S_KEY_2: + *specificLabel = 0x32534E4DU; + break; + case MC_KEY_3: + *specificLabel = 0x334B434DU; + break; + case MC_APP_S_KEY_3: + *specificLabel = 0x3353414DU; + break; + case MC_NWK_S_KEY_3: + *specificLabel = 0x33534E4DU; + break; +#endif /* LORAMAC_MAX_MC_CTX > 1 */ + default: + retval = SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + break; + } + return retval; +} -/* - * Dummy callback in case if the user provides NULL function pointer - */ -static void DummyCB(void) +static SecureElementStatus_t DeleteAllDynamicKeys( void ) { - return; + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_OBJECT_HANDLE hObject[NUM_OF_KEYS]; + uint32_t ulCount = 0; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Get all keys handle */ + if (rv == CKR_OK) + { + rv = C_FindObjectsInit(session, NULL, 0); + } + + /* Find all existing keys handle */ + if (rv == CKR_OK) + { + rv = C_FindObjects(session, hObject, NUM_OF_KEYS, (CK_ULONG *) &ulCount); + } + + if (rv == CKR_OK) + { + rv = C_FindObjectsFinal(session); + } + + if (ulCount <= NUM_OF_KEYS) + { + for (uint8_t i = 0; i < ulCount; i++) + { + /* Exclude all Embedded keys */ + if (hObject[i] > LAST_KMS_KEY_OBJECT_HANDLE) + { + if (rv == CKR_OK) + { + rv = C_DestroyObject(session, hObject[i]); + } + } + } + } + + /* Close sessions */ + if (session > 0) + { + (void)C_CloseSession(session); + } + + if (rv != CKR_OK) + { + return SECURE_ELEMENT_ERROR; + } + return SECURE_ELEMENT_SUCCESS; } +#endif /* LORAWAN_KMS */ /* * Computes a CMAC of a message using provided initial Bx block @@ -280,109 +373,107 @@ static void DummyCB(void) * \param[OUT] cmac - Computed cmac * \retval - Status of the operation */ -static SecureElementStatus_t ComputeCmac(uint8_t *micBxBuffer, uint8_t *buffer, uint16_t size, KeyIdentifier_t keyID, - uint32_t *cmac) +static SecureElementStatus_t ComputeCmac( uint8_t* micBxBuffer, uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, + uint32_t* cmac ) { - SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; - if ((buffer == NULL) || (cmac == NULL)) - { - return SECURE_ELEMENT_ERROR_NPE; - } + if( ( buffer == NULL ) || ( cmac == NULL ) ) + { + return SECURE_ELEMENT_ERROR_NPE; + } #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - uint8_t Cmac[16]; - AES_CMAC_CTX aesCmacCtx[1]; - - AES_CMAC_Init(aesCmacCtx); + uint8_t Cmac[16]; + AES_CMAC_CTX aesCmacCtx[1]; - Key_t *keyItem; - retval = GetKeyByID(keyID, &keyItem); + AES_CMAC_Init( aesCmacCtx ); - if (retval == SECURE_ELEMENT_SUCCESS) - { - AES_CMAC_SetKey(aesCmacCtx, keyItem->KeyValue); + Key_t* keyItem; + SecureElementStatus_t retval = GetKeyByID( keyID, &keyItem ); - if (micBxBuffer != NULL) + if( retval == SECURE_ELEMENT_SUCCESS ) { - AES_CMAC_Update(aesCmacCtx, micBxBuffer, 16); - } + AES_CMAC_SetKey( aesCmacCtx, keyItem->KeyValue ); - AES_CMAC_Update(aesCmacCtx, buffer, size); + if( micBxBuffer != NULL ) + { + AES_CMAC_Update( aesCmacCtx, micBxBuffer, 16 ); + } - AES_CMAC_Final(Cmac, aesCmacCtx); + AES_CMAC_Update( aesCmacCtx, buffer, size ); - /* Bring into the required format */ - *cmac = (uint32_t)((uint32_t) Cmac[3] << 24 | (uint32_t) Cmac[2] << 16 | (uint32_t) Cmac[1] << 8 | - (uint32_t) Cmac[0]); - } -#else /* LORAWAN_KMS == 1 */ - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - uint32_t tag_lenth = 0; - CK_OBJECT_HANDLE object_handle ; - - /* AES CMAC Authentication variables */ - CK_MECHANISM aes_cmac_mechanism = { CKM_AES_CMAC, (CK_VOID_PTR)NULL, 0 }; - - retval = GetKeyIndexByID(keyID, &object_handle); - if (retval != SECURE_ELEMENT_SUCCESS) - { - return retval; - } + AES_CMAC_Final( Cmac, aesCmacCtx ); - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); + // Bring into the required format + *cmac = ( uint32_t )( ( uint32_t ) Cmac[3] << 24 | ( uint32_t ) Cmac[2] << 16 | ( uint32_t ) Cmac[1] << 8 | + ( uint32_t ) Cmac[0] ); + } +#else /* LORAWAN_KMS == 1 */ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t tag_lenth = 0; + CK_OBJECT_HANDLE key_handle ; - /* Configure session to Authentication message in AES CMAC with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_SignInit(session, &aes_cmac_mechanism, object_handle); - } + /* AES CMAC Authentication variables */ + CK_MECHANISM aes_cmac_mechanism = { CKM_AES_CMAC, (CK_VOID_PTR)NULL, 0 }; - /* Encrypt clear message */ - if (rv == CKR_OK) - { - /* work around : need to double-check if possible to use micBxBuffer as IV for Sign */ - if (micBxBuffer != NULL) + SecureElementStatus_t retval = GetKeyIndexByID(keyID, &key_handle); + if (retval != SECURE_ELEMENT_SUCCESS) { - memcpy1((uint8_t *) &input_align_combined_buf[0], (uint8_t *) micBxBuffer, SE_KEY_SIZE); - memcpy1((uint8_t *) &input_align_combined_buf[SE_KEY_SIZE], (uint8_t *) buffer, size); + return retval; } - else + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Configure session to Authentication message in AES CMAC with settings included into the mechanism */ + if (rv == CKR_OK) { - memcpy1((uint8_t *) &input_align_combined_buf[0], (uint8_t *) buffer, size); + rv = C_SignInit(session, &aes_cmac_mechanism, key_handle); } - } - if (rv == CKR_OK) - { - if (micBxBuffer != NULL) + /* Encrypt clear message */ + if (rv == CKR_OK) { - rv = C_Sign(session, (CK_BYTE_PTR)&input_align_combined_buf[0], size + SE_KEY_SIZE, &tag[0], - (CK_ULONG_PTR)&tag_lenth); + /* work around : need to double-check if possible to use micBxBuffer as IV for Sign */ + if (micBxBuffer != NULL) + { + memcpy1((uint8_t *) &input_align_combined_buf[0], (uint8_t *) micBxBuffer, SE_KEY_SIZE); + memcpy1((uint8_t *) &input_align_combined_buf[SE_KEY_SIZE], (uint8_t *) buffer, size); + } + else + { + memcpy1((uint8_t *) &input_align_combined_buf[0], (uint8_t *) buffer, size); + } } - else + + if (rv == CKR_OK) { - rv = C_Sign(session, (CK_BYTE_PTR)&input_align_combined_buf[0], size, &tag[0], - (CK_ULONG_PTR)&tag_lenth); + if (micBxBuffer != NULL) + { + rv = C_Sign(session, (CK_BYTE_PTR)&input_align_combined_buf[0], size + SE_KEY_SIZE, &tag[0], + (CK_ULONG_PTR)&tag_lenth); + } + else + { + rv = C_Sign(session, (CK_BYTE_PTR)&input_align_combined_buf[0], size, &tag[0], + (CK_ULONG_PTR)&tag_lenth); + } } - } - /* Close session with KMS */ - (void)C_CloseSession(session); + /* Close session with KMS */ + (void)C_CloseSession(session); - /* combine to a 32bit authentication word (MIC) */ - *cmac = (uint32_t)((uint32_t) tag[3] << 24 | (uint32_t) tag[2] << 16 | (uint32_t) tag[1] << 8 | - (uint32_t) tag[0]); + /* combine to a 32bit authentication word (MIC) */ + *cmac = (uint32_t)((uint32_t) tag[3] << 24 | (uint32_t) tag[2] << 16 | (uint32_t) tag[1] << 8 | + (uint32_t) tag[0]); - if (rv != CKR_OK) - { - retval = SECURE_ELEMENT_ERROR; - } + if (rv != CKR_OK) + { + retval = SECURE_ELEMENT_ERROR; + } #endif /* LORAWAN_KMS */ - - return retval; + return retval; } @@ -391,609 +482,796 @@ static SecureElementStatus_t ComputeCmac(uint8_t *micBxBuffer, uint8_t *buffer, /* * API functions */ - -SecureElementStatus_t SecureElementInit(SecureElementNvmEvent seNvmCtxChanged) +/* ST_WORKAROUND: Add unique ID callback as input parameter */ +SecureElementStatus_t SecureElementInit( SecureElementNvmData_t *nvm, SecureElementGetUniqueId seGetUniqueId ) { #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - Key_t *keyItem; - SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; - - /* Initialize LoRaWAN Key List buffer */ - memcpy1((uint8_t *)(SeNvmCtx.KeyList), (const uint8_t *)InitialKeyList, sizeof(Key_t)*NUM_OF_KEYS); - - retval = GetKeyByID(APP_KEY, &keyItem); - KEY_LOG(TS_OFF, VLEVEL_M, "###### OTAA ######\r\n"); - if (retval == SECURE_ELEMENT_SUCCESS) - { - KEY_LOG(TS_OFF, VLEVEL_M, "###### AppKey: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n", HEX16(keyItem->KeyValue)); - } - retval = GetKeyByID(NWK_KEY, &keyItem); - if (retval == SECURE_ELEMENT_SUCCESS) - { - KEY_LOG(TS_OFF, VLEVEL_M, "###### NwkKey: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n", HEX16(keyItem->KeyValue)); - } - KEY_LOG(TS_OFF, VLEVEL_M, "###### ABP ######\r\n"); - retval = GetKeyByID(APP_S_KEY, &keyItem); - if (retval == SECURE_ELEMENT_SUCCESS) - { - KEY_LOG(TS_OFF, VLEVEL_M, "###### AppSKey: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n", HEX16(keyItem->KeyValue)); - } - retval = GetKeyByID(NWK_S_KEY, &keyItem); - if (retval == SECURE_ELEMENT_SUCCESS) - { - KEY_LOG(TS_OFF, VLEVEL_M, "###### NwkSKey: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n", HEX16(keyItem->KeyValue)); - } + SecureElementNvmData_t seNvmInit = + { + /*! + * end-device IEEE EUI (big endian) + * + * \remark In this application the value is automatically generated by + * calling BoardGetUniqueId function + */ + .DevEui = LORAWAN_DEVICE_EUI, + /*! + * App/Join server IEEE EUI (big endian) + */ + .JoinEui = LORAWAN_JOIN_EUI, + /*! + * LoRaWAN key list + */ + .KeyList = SOFT_SE_KEY_LIST + }; + + + if( nvm == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } + + // Initialize nvm pointer + SeNvm = nvm; + + // Initialize data + memcpy1( ( uint8_t* )SeNvm, ( uint8_t* )&seNvmInit, sizeof( seNvmInit ) ); #else /* LORAWAN_KMS == 1 */ - uint8_t itr = 0; + uint8_t itr = 0; + uint8_t devEUI[SE_EUI_SIZE] = LORAWAN_DEVICE_EUI; + uint8_t joinEUI[SE_EUI_SIZE] = LORAWAN_JOIN_EUI; + + if (nvm == NULL) + { + return SECURE_ELEMENT_ERROR_NPE; + } - // Initialize with defaults - SeNvmCtx.KeyList[itr++].KeyID = APP_KEY; - SeNvmCtx.KeyList[itr++].KeyID = NWK_KEY; + /* Initialize nvm pointer */ + SeNvm = nvm; + + /* Initialize with defaults */ + memcpy1((uint8_t *)SeNvm->DevEui, devEUI, SE_EUI_SIZE); + memcpy1((uint8_t *)SeNvm->JoinEui, joinEUI, SE_EUI_SIZE); + + SeNvm->KeyList[itr++].KeyID = APP_KEY; + SeNvm->KeyList[itr++].KeyID = NWK_KEY; #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - SeNvmCtx.KeyList[itr++].KeyID = J_S_INT_KEY; - SeNvmCtx.KeyList[itr++].KeyID = J_S_ENC_KEY; - SeNvmCtx.KeyList[itr++].KeyID = F_NWK_S_INT_KEY; - SeNvmCtx.KeyList[itr++].KeyID = S_NWK_S_INT_KEY; - SeNvmCtx.KeyList[itr++].KeyID = NWK_S_ENC_KEY; + SeNvm->KeyList[itr++].KeyID = J_S_INT_KEY; + SeNvm->KeyList[itr++].KeyID = J_S_ENC_KEY; + SeNvm->KeyList[itr++].KeyID = F_NWK_S_INT_KEY; + SeNvm->KeyList[itr++].KeyID = S_NWK_S_INT_KEY; + SeNvm->KeyList[itr++].KeyID = NWK_S_ENC_KEY; #else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ - SeNvmCtx.KeyList[itr++].KeyID = NWK_S_KEY; + SeNvm->KeyList[itr++].KeyID = NWK_S_KEY; #endif /* USE_LRWAN_1_1_X_CRYPTO */ - SeNvmCtx.KeyList[itr++].KeyID = APP_S_KEY; - SeNvmCtx.KeyList[itr++].KeyID = MC_ROOT_KEY; - SeNvmCtx.KeyList[itr++].KeyID = MC_KE_KEY; - SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_0; - SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_0; - SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_0; + SeNvm->KeyList[itr++].KeyID = APP_S_KEY; + SeNvm->KeyList[itr++].KeyID = MC_ROOT_KEY; + SeNvm->KeyList[itr++].KeyID = MC_KE_KEY; + SeNvm->KeyList[itr++].KeyID = MC_KEY_0; + SeNvm->KeyList[itr++].KeyID = MC_APP_S_KEY_0; + SeNvm->KeyList[itr++].KeyID = MC_NWK_S_KEY_0; #if ( LORAMAC_MAX_MC_CTX > 1 ) - SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_1; - SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_1; - SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_1; - SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_2; - SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_2; - SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_2; - SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_3; - SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_3; - SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_3; + SeNvm->KeyList[itr++].KeyID = MC_KEY_1; + SeNvm->KeyList[itr++].KeyID = MC_APP_S_KEY_1; + SeNvm->KeyList[itr++].KeyID = MC_NWK_S_KEY_1; + SeNvm->KeyList[itr++].KeyID = MC_KEY_2; + SeNvm->KeyList[itr++].KeyID = MC_APP_S_KEY_2; + SeNvm->KeyList[itr++].KeyID = MC_NWK_S_KEY_2; + SeNvm->KeyList[itr++].KeyID = MC_KEY_3; + SeNvm->KeyList[itr++].KeyID = MC_APP_S_KEY_3; + SeNvm->KeyList[itr++].KeyID = MC_NWK_S_KEY_3; #endif /*LORAMAC_MAX_MC_CTX > 1 */ - SeNvmCtx.KeyList[itr].KeyID = SLOT_RAND_ZERO_KEY; - + SeNvm->KeyList[itr].KeyID = SLOT_RAND_ZERO_KEY; + + /* Delete all obsolete keys in NVM */ + DeleteAllDynamicKeys(); + + SecureElementSetObjHandler(APP_KEY, KMS_APP_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(NWK_KEY, KMS_NWK_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(APP_S_KEY, KMS_APP_S_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(NWK_S_KEY, KMS_NWK_S_KEY_OBJECT_HANDLE); +#if ( LORAMAC_CLASSB_ENABLED == 1 ) + SecureElementSetObjHandler(SLOT_RAND_ZERO_KEY, KMS_ZERO_KEY_OBJECT_HANDLE); +#endif /* LORAMAC_CLASSB_ENABLED */ #endif /* LORAWAN_KMS */ - /* Assign callback */ - if (seNvmCtxChanged != 0) - { - SeNvmCtxChanged = seNvmCtxChanged; - } - else - { - SeNvmCtxChanged = DummyCB; - } +#if (defined (KEY_EXTRACTABLE) && (KEY_EXTRACTABLE == 1)) + MW_LOG(TS_OFF, VLEVEL_M, "###### OTAA ######\r\n"); + PrintKey(APP_KEY); + PrintKey(NWK_KEY); + MW_LOG(TS_OFF, VLEVEL_M, "###### ABP ######\r\n"); + PrintKey(APP_S_KEY); + PrintKey(NWK_S_KEY); +#endif /* KEY_EXTRACTABLE */ #if !defined( SECURE_ELEMENT_PRE_PROVISIONED ) -#if ( STATIC_DEVICE_EUI == 0 ) - /* Get a DevEUI from MCU unique ID */ - GetUniqueId(SeNvmCtx.DevEui); +#if( STATIC_DEVICE_EUI == 0 ) + if (seGetUniqueId != NULL) + { + // Get a DevEUI from MCU unique ID + seGetUniqueId(SeNvm->DevEui); + } #endif /* STATIC_DEVICE_EUI */ #endif /* !SECURE_ELEMENT_PRE_PROVISIONED */ - SeNvmCtxChanged(); - - return SECURE_ELEMENT_SUCCESS; + return SECURE_ELEMENT_SUCCESS; } -SecureElementStatus_t SecureElementDeleteDerivedKeys(uint8_t *kms_key_label) +/* ST_WORKAROUND_BEGIN: Add KMS specific functions */ +SecureElementStatus_t SecureElementGetKeyByID( KeyIdentifier_t keyID, Key_t **keyItem ) { #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - return SECURE_ELEMENT_ERROR; +#if (defined (KEY_EXTRACTABLE) && (KEY_EXTRACTABLE == 1)) + for (uint8_t i = 0; i < NUM_OF_KEYS; i++) + { + if (SeNvm->KeyList[i].KeyID == keyID) + { + *keyItem = &(SeNvm->KeyList[i]); + return SECURE_ELEMENT_SUCCESS; + } + } +#endif /* KEY_EXTRACTABLE */ + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; #else /* LORAWAN_KMS == 1 */ - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); - - /* Work Around: waiting for bugzilla Ticket 80990 */ - /* Be sure there are no remaining derived key in the NVM */ - /* The problem is that today there is no a Close session procedure */ - /* on the other hand this could erase keys generated by the application */ - /* so be very careful with this ... */ - if (rv == CKR_OK) - { - rv = C_DestroyObject(session, 50); /* KMS_INDEX_MIN_NVM_DYNAMIC_OBJECTS = 50 */ - rv = C_DestroyObject(session, 51); - rv = C_DestroyObject(session, 52); - rv = C_DestroyObject(session, 53); - rv = C_DestroyObject(session, 54); - rv = C_DestroyObject(session, 55); - rv = C_DestroyObject(session, 56); - rv = C_DestroyObject(session, 57); /* from kms_platf_objects_interface.h we use max 8 objects */ - } - else - { - return SECURE_ELEMENT_ERROR; - } + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_OBJECT_HANDLE key_handle = (CK_OBJECT_HANDLE)(~0UL); + CK_ULONG derive_key_template_class = CKO_SECRET_KEY; + uint8_t extractable_key[16] = {0}; + CK_ATTRIBUTE key_attribute_template = {CKA_VALUE, (CK_VOID_PTR) &derive_key_template_class, 16UL}; + uint8_t index_keylist = 0; + for (index_keylist = 0; index_keylist < NUM_OF_KEYS; index_keylist++) + { + if (SeNvm->KeyList[index_keylist].KeyID == keyID) + { + key_handle = SeNvm->KeyList[index_keylist].Object_Index; + break; + } + } + if (key_handle == (CK_OBJECT_HANDLE)(~0UL)) + { + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + } - /* Close sessions */ - if (session > 0) - { + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Get key to display */ + if (rv == CKR_OK) + { + key_attribute_template.pValue = extractable_key; + rv = C_GetAttributeValue(session, key_handle, &key_attribute_template, 1UL); + } + if (rv == CKR_OK) + { + memcpy1(SeNvm->KeyList[index_keylist].KeyValue, extractable_key, sizeof(extractable_key)); + *keyItem = &(SeNvm->KeyList[index_keylist]); + } + + /* Close sessions */ (void)C_CloseSession(session); - } - return SECURE_ELEMENT_SUCCESS; + + if (rv != CKR_OK) + { + return SECURE_ELEMENT_ERROR; + } + return SECURE_ELEMENT_SUCCESS; + #endif /* LORAWAN_KMS == 1 */ } -SecureElementStatus_t SecureElementRestoreNvmCtx(void *seNvmCtx) +SecureElementStatus_t SecureElementDeleteDynamicKeys( KeyIdentifier_t keyID, uint32_t *key_label ) { - /* Restore nvm context */ - if (seNvmCtx != 0) - { - memcpy1((uint8_t *) &SeNvmCtx, (uint8_t *) seNvmCtx, sizeof(SeNvmCtx)); +#if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) + return SECURE_ELEMENT_ERROR; +#else /* LORAWAN_KMS == 1 */ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_OBJECT_HANDLE hObject[NUM_OF_KEYS]; + CK_ULONG local_template_label[] = {GlobalTemplateLabel, 0UL}; + CK_ATTRIBUTE dynamic_key_template = {CKA_LABEL, (CK_VOID_PTR)local_template_label, sizeof(local_template_label)}; + uint32_t ulCount = 0; + + if (SECURE_ELEMENT_SUCCESS != GetSpecificLabelByID(keyID, &local_template_label[1])) + { + return SECURE_ELEMENT_ERROR; + } + *key_label = local_template_label[1]; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Search from Template pattern */ + if (rv == CKR_OK) + { + rv = C_FindObjectsInit(session, &dynamic_key_template, sizeof(dynamic_key_template) / sizeof(CK_ATTRIBUTE)); + } + + /* Find all existing keys handle Template pattern */ + if (rv == CKR_OK) + { + rv = C_FindObjects(session, hObject, NUM_OF_KEYS, (CK_ULONG *) &ulCount); + } + + if (rv == CKR_OK) + { + rv = C_FindObjectsFinal(session); + } + + if (ulCount <= NUM_OF_KEYS) + { + for (uint8_t i = 0; i < ulCount; i++) + { + if (rv == CKR_OK) + { + rv = C_DestroyObject(session, hObject[i]); + } + } + } + + /* Close sessions */ + if (session > 0) + { + (void)C_CloseSession(session); + } + + if (rv != CKR_OK) + { + return SECURE_ELEMENT_ERROR; + } return SECURE_ELEMENT_SUCCESS; - } - else - { - return SECURE_ELEMENT_ERROR_NPE; - } +#endif /* LORAWAN_KMS == 1 */ } -void *SecureElementGetNvmCtx(size_t *seNvmCtxSize) +SecureElementStatus_t SecureElementSetObjHandler( KeyIdentifier_t keyID, uint32_t keyIndex ) { - *seNvmCtxSize = sizeof(SeNvmCtx); - return &SeNvmCtx; +#if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) + return SECURE_ELEMENT_ERROR; +#else /* LORAWAN_KMS == 1 */ + for (uint8_t i = 0; i < NUM_OF_KEYS; i++) + { + if (SeNvm->KeyList[i].KeyID == keyID) + { + SeNvm->KeyList[i].Object_Index = (CK_OBJECT_HANDLE) keyIndex; + return SECURE_ELEMENT_SUCCESS; + } + } + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; +#endif /* LORAWAN_KMS */ } +/* ST_WORKAROUND_END */ -SecureElementStatus_t SecureElementSetKey(KeyIdentifier_t keyID, uint8_t *key) +SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ) { - if (key == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } + if( key == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - for (uint8_t i = 0; i < NUM_OF_KEYS; i++) - { - if (SeNvmCtx.KeyList[i].KeyID == keyID) + for( uint8_t i = 0; i < NUM_OF_KEYS; i++ ) + { + if( SeNvm->KeyList[i].KeyID == keyID ) + { + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ +#if ( LORAMAC_MAX_MC_CTX == 1 ) + if ( keyID == MC_KEY_0 ) +#else /* LORAMAC_MAX_MC_CTX > 1 */ + if( ( keyID == MC_KEY_0 ) || ( keyID == MC_KEY_1 ) || ( keyID == MC_KEY_2 ) || ( keyID == MC_KEY_3 ) ) +#endif /* LORAMAC_MAX_MC_CTX */ + /* ST_WORKAROUND_END */ + { // Decrypt the key if its a Mckey + SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; + uint8_t decryptedKey[16] = { 0 }; + + retval = SecureElementAesEncrypt( key, 16, MC_KE_KEY, decryptedKey ); + + memcpy1( SeNvm->KeyList[i].KeyValue, decryptedKey, SE_KEY_SIZE ); + return retval; + } + else + { + memcpy1( SeNvm->KeyList[i].KeyValue, key, SE_KEY_SIZE ); + return SECURE_ELEMENT_SUCCESS; + } + } + } + + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; +#else /* LORAWAN_KMS == 1 */ + SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_OBJECT_HANDLE key_handle; + CK_ULONG template_class = CKO_SECRET_KEY; + CK_ULONG template_type = CKK_AES; +#if (defined (KEY_EXTRACTABLE) && (KEY_EXTRACTABLE == 1)) + CK_ULONG template_true = CK_TRUE; +#else + CK_ULONG template_false = CK_TRUE; +#endif /* KEY_EXTRACTABLE */ + uint32_t key_ui32[] = + { + key[3] | (key[2] << 8) | (key[1] << 16) | (key[0] << 24), + key[7] | (key[6] << 8) | (key[5] << 16) | (key[4] << 24), + key[11] | (key[10] << 8) | (key[9] << 16) | (key[8] << 24), + key[15] | (key[14] << 8) | (key[13] << 16) | (key[12] << 24), + }; + + uint32_t specific_label[] = {GlobalTemplateLabel, 0UL}; + CK_ATTRIBUTE key_attribute_template[] = { + { CKA_CLASS, (CK_VOID_PTR) &template_class, sizeof(CK_BBOOL) }, + { CKA_KEY_TYPE, (CK_VOID_PTR) &template_type, sizeof(CK_BBOOL) }, + { CKA_VALUE, (CK_VOID_PTR)key_ui32, sizeof(key_ui32) }, +#if (defined (KEY_EXTRACTABLE) && (KEY_EXTRACTABLE == 1)) + { CKA_EXTRACTABLE, (CK_VOID_PTR) &template_true, sizeof(CK_BBOOL) }, +#else + { CKA_EXTRACTABLE, (CK_VOID_PTR) &template_false, sizeof(CK_BBOOL) }, +#endif /* KEY_EXTRACTABLE */ + { CKA_LABEL, (CK_VOID_PTR)specific_label, sizeof(specific_label)}, + }; + + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ #if ( LORAMAC_MAX_MC_CTX == 1 ) - if (keyID == MC_KEY_0) + if ( keyID == MC_KEY_0 ) #else /* LORAMAC_MAX_MC_CTX > 1 */ - if ((keyID == MC_KEY_0) || (keyID == MC_KEY_1) || (keyID == MC_KEY_2) || (keyID == MC_KEY_3)) + if( ( keyID == MC_KEY_0 ) || ( keyID == MC_KEY_1 ) || ( keyID == MC_KEY_2 ) || ( keyID == MC_KEY_3 ) ) #endif /* LORAMAC_MAX_MC_CTX */ - { - /* Decrypt the key if its a Mckey */ - SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; + /* ST_WORKAROUND_END */ + { // Decrypt the key if its a Mckey uint8_t decryptedKey[16] = { 0 }; + if (SECURE_ELEMENT_SUCCESS != SecureElementAesEncrypt( key, 16, MC_KE_KEY, decryptedKey )) + { + return SECURE_ELEMENT_ERROR; + } + + key_ui32[0] = decryptedKey[3] | (decryptedKey[2] << 8) | (decryptedKey[1] << 16) | (decryptedKey[0] << 24); + key_ui32[1] = decryptedKey[7] | (decryptedKey[6] << 8) | (decryptedKey[5] << 16) | (decryptedKey[4] << 24); + key_ui32[2] = decryptedKey[11] | (decryptedKey[10] << 8) | (decryptedKey[9] << 16) | (decryptedKey[8] << 24); + key_ui32[3] = decryptedKey[15] | (decryptedKey[14] << 8) | (decryptedKey[13] << 16) | (decryptedKey[12] << 24); + } - retval = SecureElementAesEncrypt(key, 16, MC_KE_KEY, decryptedKey); + if (SECURE_ELEMENT_SUCCESS != GetKeyIndexByID(keyID, &key_handle)) + { + return SECURE_ELEMENT_ERROR; + } - memcpy1(SeNvmCtx.KeyList[i].KeyValue, decryptedKey, SE_KEY_SIZE); - SeNvmCtxChanged(); + if (SECURE_ELEMENT_SUCCESS != SecureElementDeleteDynamicKeys(keyID, &specific_label[1])) + { + return SECURE_ELEMENT_ERROR; + } - return retval; - } - else - { - memcpy1(SeNvmCtx.KeyList[i].KeyValue, key, SE_KEY_SIZE); - SeNvmCtxChanged(); - return SECURE_ELEMENT_SUCCESS; - } - } - } - return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; -#else /* LORAWAN_KMS == 1 */ - /* Indexes are already stored at init or when deriving the key */ - CK_OBJECT_HANDLE keyIndex; - return GetKeyIndexByID(keyID, &keyIndex); -#endif /* LORAWAN_KMS */ -} + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); -SecureElementStatus_t SecureElementSetObjHandler(KeyIdentifier_t keyID, uint32_t keyIndex) -{ -#if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - return SECURE_ELEMENT_ERROR; -#else /* LORAWAN_KMS == 1 */ - for (uint8_t i = 0; i < NUM_OF_KEYS; i++) - { - if (SeNvmCtx.KeyList[i].KeyID == keyID) + /* Get key to display */ + if (rv == CKR_OK) + { + rv = C_CreateObject(session, key_attribute_template, sizeof(key_attribute_template) / sizeof(CK_ATTRIBUTE), + &key_handle); + } + + if (rv == CKR_OK) + { + retval = SecureElementSetObjHandler(keyID, key_handle); + } + + PrintKey(keyID); + + /* Close sessions */ + (void)C_CloseSession(session); + + if (rv != CKR_OK) { - SeNvmCtx.KeyList[i].Object_Index = (CK_OBJECT_HANDLE) keyIndex; - SeNvmCtxChanged(); - return SECURE_ELEMENT_SUCCESS; + retval = SECURE_ELEMENT_ERROR; } - } - return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + return retval; #endif /* LORAWAN_KMS */ } -SecureElementStatus_t SecureElementComputeAesCmac(uint8_t *micBxBuffer, uint8_t *buffer, uint16_t size, - KeyIdentifier_t keyID, uint32_t *cmac) +SecureElementStatus_t SecureElementComputeAesCmac( uint8_t* micBxBuffer, uint8_t* buffer, uint16_t size, + KeyIdentifier_t keyID, uint32_t* cmac ) { - if (keyID >= LORAMAC_CRYPTO_MULTICAST_KEYS) - { - /* Never accept multicast key identifier for cmac computation */ - return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; - } + if( keyID >= LORAMAC_CRYPTO_MULTICAST_KEYS ) + { + // Never accept multicast key identifier for cmac computation + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + } - return ComputeCmac(micBxBuffer, buffer, size, keyID, cmac); + return ComputeCmac( micBxBuffer, buffer, size, keyID, cmac ); } -SecureElementStatus_t SecureElementVerifyAesCmac(uint8_t *buffer, uint16_t size, uint32_t expectedCmac, - KeyIdentifier_t keyID) +SecureElementStatus_t SecureElementVerifyAesCmac( uint8_t* buffer, uint16_t size, uint32_t expectedCmac, + KeyIdentifier_t keyID ) { - SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; - if (buffer == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } + if( buffer == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } + SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - uint32_t compCmac = 0; - - retval = ComputeCmac(NULL, buffer, size, keyID, &compCmac); - if (retval != SECURE_ELEMENT_SUCCESS) - { - return retval; - } + uint32_t compCmac = 0; + retval = ComputeCmac( NULL, buffer, size, keyID, &compCmac ); + if( retval != SECURE_ELEMENT_SUCCESS ) + { + return retval; + } - if (expectedCmac != compCmac) - { - retval = SECURE_ELEMENT_FAIL_CMAC; - } + if( expectedCmac != compCmac ) + { + retval = SECURE_ELEMENT_FAIL_CMAC; + } #else /* LORAWAN_KMS == 1 */ - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - CK_OBJECT_HANDLE object_handle; - - if (buffer == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } - - /* AES CMAC Authentication variables */ - CK_MECHANISM aes_cmac_mechanism = { CKM_AES_CMAC, (CK_VOID_PTR)NULL, 0 }; - - retval = GetKeyIndexByID(keyID, &object_handle); - if (retval != SECURE_ELEMENT_SUCCESS) - { - return retval; - } + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_OBJECT_HANDLE object_handle; - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); + if (buffer == NULL) + { + return SECURE_ELEMENT_ERROR_NPE; + } - /* Configure session to Verify the message in AES CMAC with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_VerifyInit(session, &aes_cmac_mechanism, object_handle); - } + /* AES CMAC Authentication variables */ + CK_MECHANISM aes_cmac_mechanism = { CKM_AES_CMAC, (CK_VOID_PTR)NULL, 0 }; - /* Verify the message */ - if (rv == CKR_OK) - { - memcpy1(input_align_combined_buf, buffer, size); - rv = C_Verify(session, (CK_BYTE_PTR)input_align_combined_buf, size, (CK_BYTE_PTR)&expectedCmac, 4); - } + retval = GetKeyIndexByID(keyID, &object_handle); + if (retval != SECURE_ELEMENT_SUCCESS) + { + return retval; + } - (void)C_CloseSession(session); + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); - if (rv != CKR_OK) - { - retval = SECURE_ELEMENT_ERROR; - } + /* Configure session to Verify the message in AES CMAC with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_VerifyInit(session, &aes_cmac_mechanism, object_handle); + } + + /* Verify the message */ + if (rv == CKR_OK) + { + memcpy1(input_align_combined_buf, buffer, size); + rv = C_Verify(session, (CK_BYTE_PTR)input_align_combined_buf, size, (CK_BYTE_PTR)&expectedCmac, 4); + } + + (void)C_CloseSession(session); + + if (rv != CKR_OK) + { + retval = SECURE_ELEMENT_ERROR; + } #endif /* LORAWAN_KMS */ - return retval; + return retval; } -SecureElementStatus_t SecureElementAesEncrypt(uint8_t *buffer, uint16_t size, KeyIdentifier_t keyID, - uint8_t *encBuffer) +SecureElementStatus_t SecureElementAesEncrypt( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, + uint8_t* encBuffer ) { - SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; - if (buffer == NULL || encBuffer == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } - - /* Check if the size is divisible by 16 */ - if ((size % 16) != 0) - { - return SECURE_ELEMENT_ERROR_BUF_SIZE; - } + if( buffer == NULL || encBuffer == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } + + // Check if the size is divisible by 16, + if( ( size % 16 ) != 0 ) + { + return SECURE_ELEMENT_ERROR_BUF_SIZE; + } #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - lorawan_aes_context aesContext; - memset1(aesContext.ksch, '\0', 240); + lorawan_aes_context aesContext; + memset1( aesContext.ksch, '\0', 240 ); - Key_t *pItem; - retval = GetKeyByID(keyID, &pItem); + Key_t* pItem; + SecureElementStatus_t retval = GetKeyByID( keyID, &pItem ); - if (retval == SECURE_ELEMENT_SUCCESS) - { - lorawan_aes_set_key(pItem->KeyValue, 16, &aesContext); + if( retval == SECURE_ELEMENT_SUCCESS ) + { + lorawan_aes_set_key(pItem->KeyValue, 16, &aesContext); - uint8_t block = 0; + uint8_t block = 0; - while (size != 0) - { - lorawan_aes_encrypt(&buffer[block], &encBuffer[block], &aesContext); - block = block + 16; - size = size - 16; + while( size != 0 ) + { + lorawan_aes_encrypt(&buffer[block], &encBuffer[block], &aesContext); + block = block + 16; + size = size - 16; + } } - } #else /* LORAWAN_KMS == 1 */ - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - uint32_t encrypted_length = 0; - CK_OBJECT_HANDLE object_handle; - uint8_t dummy_tag[SE_KEY_SIZE] = {0}; - uint32_t dummy_tag_lenth = 0; - - CK_MECHANISM aes_ecb_mechanism = { CKM_AES_ECB, (CK_VOID_PTR *) NULL, 0 }; - - retval = GetKeyIndexByID(keyID, &object_handle); - if (retval != SECURE_ELEMENT_SUCCESS) - { - return retval; - } - - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); - - /* Configure session to encrypt message in AES ECB with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_EncryptInit(session, &aes_ecb_mechanism, object_handle); - } - - /* Encrypt clear message */ - if (rv == CKR_OK) - { - memcpy1(input_align_combined_buf, buffer, size); - encrypted_length = sizeof(output_align); - rv = C_EncryptUpdate(session, (CK_BYTE_PTR)input_align_combined_buf, size, - output_align, (CK_ULONG_PTR)&encrypted_length); - memcpy1(encBuffer, output_align, size); - } - - /* In this case C_EncryptFinal is just called to Free the Alloc mem */ - if (rv == CKR_OK) - { - dummy_tag_lenth = sizeof(tag); - rv = C_EncryptFinal(session, &dummy_tag[0], (CK_ULONG_PTR)&dummy_tag_lenth); - } - - /* Close session with KMS */ - (void)C_CloseSession(session); - - if (rv != CKR_OK) - { - retval = SECURE_ELEMENT_ERROR; - } + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t encrypted_length = 0; + CK_OBJECT_HANDLE object_handle; + uint8_t dummy_tag[SE_KEY_SIZE] = {0}; + uint32_t dummy_tag_lenth = 0; + + CK_MECHANISM aes_ecb_mechanism = { CKM_AES_ECB, (CK_VOID_PTR *) NULL, 0 }; + + SecureElementStatus_t retval = GetKeyIndexByID(keyID, &object_handle); + if (retval != SECURE_ELEMENT_SUCCESS) + { + return retval; + } + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Configure session to encrypt message in AES ECB with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_EncryptInit(session, &aes_ecb_mechanism, object_handle); + } + + /* Encrypt clear message */ + if (rv == CKR_OK) + { + memcpy1(input_align_combined_buf, buffer, size); + encrypted_length = sizeof(output_align); + rv = C_EncryptUpdate(session, (CK_BYTE_PTR)input_align_combined_buf, size, + output_align, (CK_ULONG_PTR)&encrypted_length); + memcpy1(encBuffer, output_align, size); + } + + /* In this case C_EncryptFinal is just called to Free the Alloc mem */ + if (rv == CKR_OK) + { + dummy_tag_lenth = sizeof(tag); + rv = C_EncryptFinal(session, &dummy_tag[0], (CK_ULONG_PTR)&dummy_tag_lenth); + } + + /* Close session with KMS */ + (void)C_CloseSession(session); + + if (rv != CKR_OK) + { + retval = SECURE_ELEMENT_ERROR; + } #endif /* LORAWAN_KMS */ - return retval; + return retval; } -SecureElementStatus_t SecureElementDeriveAndStoreKey(Version_t version, uint8_t *input, KeyIdentifier_t rootKeyID, - KeyIdentifier_t targetKeyID) +SecureElementStatus_t SecureElementDeriveAndStoreKey( uint8_t* input, KeyIdentifier_t rootKeyID, + KeyIdentifier_t targetKeyID ) { - SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; - if (input == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } + if( input == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } - /* In case of MC_KE_KEY, only McRootKey can be used as root key */ - if (targetKeyID == MC_KE_KEY) - { - if (rootKeyID != MC_ROOT_KEY) + SecureElementStatus_t retval = SECURE_ELEMENT_ERROR; + + // In case of MC_KE_KEY, only McRootKey can be used as root key + if( targetKeyID == MC_KE_KEY ) { - return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + if( rootKeyID != MC_ROOT_KEY ) + { + return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; + } } - } #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) - uint8_t key[16] = { 0 }; - /* Derive key */ - retval = SecureElementAesEncrypt(input, 16, rootKeyID, key); - if (retval != SECURE_ELEMENT_SUCCESS) - { - return retval; - } + uint8_t key[16] = { 0 }; + // Derive key + retval = SecureElementAesEncrypt( input, 16, rootKeyID, key ); + if( retval != SECURE_ELEMENT_SUCCESS ) + { + return retval; + } - /* Store key */ - retval = SecureElementSetKey(targetKeyID, key); - if (retval != SECURE_ELEMENT_SUCCESS) - { - return retval; - } + // Store key + retval = SecureElementSetKey( targetKeyID, key ); + if( retval != SECURE_ELEMENT_SUCCESS ) + { + return retval; + } + + return SECURE_ELEMENT_SUCCESS; #else /* LORAWAN_KMS == 1 */ - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - /* Key derivation */ - CK_MECHANISM mech = {CKM_AES_ECB_ENCRYPT_DATA, input, SE_KEY_SIZE}; - CK_OBJECT_HANDLE derivedKeyHdle; - CK_OBJECT_HANDLE rootkey_object_handle; - - /* Derive key */ - retval = GetKeyIndexByID(rootKeyID, &rootkey_object_handle); - if (retval != SECURE_ELEMENT_SUCCESS) - { + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + /* Key derivation */ + CK_MECHANISM mech = {CKM_AES_ECB_ENCRYPT_DATA, input, SE_KEY_SIZE}; + CK_OBJECT_HANDLE derived_object_handle; + CK_OBJECT_HANDLE rootkey_object_handle; + uint32_t specific_label[] = {GlobalTemplateLabel, 0UL}; + CK_ATTRIBUTE DeriveKey_template = {CKA_LABEL, (CK_VOID_PTR)specific_label, sizeof(specific_label)}; + + /* Derive key */ + if (SECURE_ELEMENT_SUCCESS != GetKeyIndexByID(rootKeyID, &rootkey_object_handle)) + { + return SECURE_ELEMENT_ERROR; + } + + if (SECURE_ELEMENT_SUCCESS != GetKeyIndexByID(targetKeyID, &derived_object_handle)) + { + return SECURE_ELEMENT_ERROR; + } + + if (SECURE_ELEMENT_SUCCESS != SecureElementDeleteDynamicKeys(targetKeyID, &specific_label[1])) + { + return SECURE_ELEMENT_ERROR; + } + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Derive key with pass phrase */ + if (rv == CKR_OK) + { + rv = C_DeriveKey(session, &(mech), rootkey_object_handle, + &DeriveKey_template, sizeof(DeriveKey_template) / sizeof(CK_ATTRIBUTE), &derived_object_handle); + } + + if (rv == CKR_OK) + { + /* Store Derived Index in table */ + retval = SecureElementSetObjHandler(targetKeyID, derived_object_handle); + } + + PrintKey(targetKeyID); + + /* Close session with KMS */ + (void)C_CloseSession(session); + + if (rv != CKR_OK) + { + retval = SECURE_ELEMENT_ERROR; + } return retval; - } - - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); - - /* Derive key with pass phrase */ - if (rv == CKR_OK) - { - rv = C_DeriveKey(session, &(mech), rootkey_object_handle, - &DeriveKey_template[0], sizeof(DeriveKey_template) / sizeof(CK_ATTRIBUTE), &derivedKeyHdle); - } - - if (rv == CKR_OK) - { - /* Store Derived Index in table */ - retval = SecureElementSetObjHandler(targetKeyID, derivedKeyHdle); - } - - /* Close session with KMS */ - (void)C_CloseSession(session); - - if (rv != CKR_OK) - { - retval = SECURE_ELEMENT_ERROR; - } #endif /* LORAWAN_KMS */ - - return retval; } -SecureElementStatus_t SecureElementProcessJoinAccept(JoinReqIdentifier_t joinReqType, uint8_t *joinEui, - uint16_t devNonce, uint8_t *encJoinAccept, - uint8_t encJoinAcceptSize, uint8_t *decJoinAccept, - uint8_t *versionMinor) +SecureElementStatus_t SecureElementProcessJoinAccept( JoinReqIdentifier_t joinReqType, uint8_t* joinEui, + uint16_t devNonce, uint8_t* encJoinAccept, + uint8_t encJoinAcceptSize, uint8_t* decJoinAccept, + uint8_t* versionMinor ) { - if ((encJoinAccept == NULL) || (decJoinAccept == NULL) || (versionMinor == NULL)) - { - return SECURE_ELEMENT_ERROR_NPE; - } + if( ( encJoinAccept == NULL ) || ( decJoinAccept == NULL ) || ( versionMinor == NULL ) ) + { + return SECURE_ELEMENT_ERROR_NPE; + } - /* Check that frame size isn't bigger than a JoinAccept with CFList size */ - if (encJoinAcceptSize > LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE) - { - return SECURE_ELEMENT_ERROR_BUF_SIZE; - } + // Check that frame size isn't bigger than a JoinAccept with CFList size + if( encJoinAcceptSize > LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE ) + { + return SECURE_ELEMENT_ERROR_BUF_SIZE; + } - /* Determine decryption key */ - KeyIdentifier_t encKeyID = NWK_KEY; + // Determine decryption key + KeyIdentifier_t encKeyID = NWK_KEY; + /* ST_WORKAROUND_BEGIN: Keep NWK_KEY if 1.1.x keys are not defined */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - if (joinReqType != JOIN_REQ) - { - encKeyID = J_S_ENC_KEY; - } + if( joinReqType != JOIN_REQ ) + { + encKeyID = J_S_ENC_KEY; + } #endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ - memcpy1(decJoinAccept, encJoinAccept, encJoinAcceptSize); + memcpy1( decJoinAccept, encJoinAccept, encJoinAcceptSize ); - /* Decrypt JoinAccept, skip MHDR */ - if (SecureElementAesEncrypt(encJoinAccept + LORAMAC_MHDR_FIELD_SIZE, encJoinAcceptSize - LORAMAC_MHDR_FIELD_SIZE, - encKeyID, decJoinAccept + LORAMAC_MHDR_FIELD_SIZE) != SECURE_ELEMENT_SUCCESS) - { - return SECURE_ELEMENT_FAIL_ENCRYPT; - } + // Decrypt JoinAccept, skip MHDR + if( SecureElementAesEncrypt( encJoinAccept + LORAMAC_MHDR_FIELD_SIZE, encJoinAcceptSize - LORAMAC_MHDR_FIELD_SIZE, + encKeyID, decJoinAccept + LORAMAC_MHDR_FIELD_SIZE ) != SECURE_ELEMENT_SUCCESS ) + { + return SECURE_ELEMENT_FAIL_ENCRYPT; + } - *versionMinor = ((decJoinAccept[11] & 0x80) == 0x80) ? 1 : 0; + *versionMinor = ( ( decJoinAccept[11] & 0x80 ) == 0x80 ) ? 1 : 0; - uint32_t mic = 0; + uint32_t mic = 0; - mic = ((uint32_t) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE] << 0); - mic |= ((uint32_t) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE + 1] << 8); - mic |= ((uint32_t) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE + 2] << 16); - mic |= ((uint32_t) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE + 3] << 24); + mic = ( ( uint32_t ) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE] << 0 ); + mic |= ( ( uint32_t ) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE + 1] << 8 ); + mic |= ( ( uint32_t ) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE + 2] << 16 ); + mic |= ( ( uint32_t ) decJoinAccept[encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE + 3] << 24 ); - /* - Header buffer to be used for MIC computation - * - LoRaWAN 1.0.x : micHeader = [MHDR(1)] - * - LoRaWAN 1.1.x : micHeader = [JoinReqType(1), JoinEUI(8), DevNonce(2), MHDR(1)] */ + // - Header buffer to be used for MIC computation + // - LoRaWAN 1.0.x : micHeader = [MHDR(1)] + // - LoRaWAN 1.1.x : micHeader = [JoinReqType(1), JoinEUI(8), DevNonce(2), MHDR(1)] - /* Verify mic */ - if (*versionMinor == 0) - { - /* For LoRaWAN 1.0.x - * cmac = aes128_cmac(NwkKey, MHDR | JoinNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | - * CFListType) */ - if (SecureElementVerifyAesCmac(decJoinAccept, (encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE), mic, NWK_KEY) != - SECURE_ELEMENT_SUCCESS) + // Verify mic + if( *versionMinor == 0 ) { - return SECURE_ELEMENT_FAIL_CMAC; + // For LoRaWAN 1.0.x + // cmac = aes128_cmac(NwkKey, MHDR | JoinNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | + // CFListType) + if( SecureElementVerifyAesCmac( decJoinAccept, ( encJoinAcceptSize - LORAMAC_MIC_FIELD_SIZE ), mic, NWK_KEY ) != + SECURE_ELEMENT_SUCCESS ) + { + return SECURE_ELEMENT_FAIL_CMAC; + } } - } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - else if (*versionMinor == 1) - { - uint8_t micHeader11[JOIN_ACCEPT_MIC_COMPUTATION_OFFSET] = { 0 }; - uint16_t bufItr = 0; +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) + else if( *versionMinor == 1 ) + { + uint8_t micHeader11[JOIN_ACCEPT_MIC_COMPUTATION_OFFSET] = { 0 }; + uint16_t bufItr = 0; - micHeader11[bufItr++] = (uint8_t) joinReqType; + micHeader11[bufItr++] = ( uint8_t ) joinReqType; - memcpyr(micHeader11 + bufItr, joinEui, LORAMAC_JOIN_EUI_FIELD_SIZE); - bufItr += LORAMAC_JOIN_EUI_FIELD_SIZE; + memcpyr( micHeader11 + bufItr, joinEui, LORAMAC_JOIN_EUI_FIELD_SIZE ); + bufItr += LORAMAC_JOIN_EUI_FIELD_SIZE; - micHeader11[bufItr++] = devNonce & 0xFF; - micHeader11[bufItr++] = (devNonce >> 8) & 0xFF; + micHeader11[bufItr++] = devNonce & 0xFF; + micHeader11[bufItr++] = ( devNonce >> 8 ) & 0xFF; - /* For LoRaWAN 1.1.x and later: - * cmac = aes128_cmac(JSIntKey, JoinReqType | JoinEUI | DevNonce | MHDR | JoinNonce | NetID | DevAddr | - * DLSettings | RxDelay | CFList | CFListType) - * Prepare the msg for integrity check (adding JoinReqType, JoinEUI and DevNonce) */ - uint8_t localBuffer[LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE + JOIN_ACCEPT_MIC_COMPUTATION_OFFSET] = { 0 }; + // For LoRaWAN 1.1.x and later: + // cmac = aes128_cmac(JSIntKey, JoinReqType | JoinEUI | DevNonce | MHDR | JoinNonce | NetID | DevAddr | + // DLSettings | RxDelay | CFList | CFListType) + // Prepare the msg for integrity check (adding JoinReqType, JoinEUI and DevNonce) + uint8_t localBuffer[LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE + JOIN_ACCEPT_MIC_COMPUTATION_OFFSET] = { 0 }; - memcpy1(localBuffer, micHeader11, JOIN_ACCEPT_MIC_COMPUTATION_OFFSET); - memcpy1(localBuffer + JOIN_ACCEPT_MIC_COMPUTATION_OFFSET - 1, decJoinAccept, encJoinAcceptSize); + memcpy1( localBuffer, micHeader11, JOIN_ACCEPT_MIC_COMPUTATION_OFFSET ); + memcpy1( localBuffer + JOIN_ACCEPT_MIC_COMPUTATION_OFFSET - 1, decJoinAccept, encJoinAcceptSize ); - if (SecureElementVerifyAesCmac(localBuffer, - encJoinAcceptSize + JOIN_ACCEPT_MIC_COMPUTATION_OFFSET - - LORAMAC_MHDR_FIELD_SIZE - LORAMAC_MIC_FIELD_SIZE, - mic, J_S_INT_KEY) != SECURE_ELEMENT_SUCCESS) - { - return SECURE_ELEMENT_FAIL_CMAC; + if( SecureElementVerifyAesCmac( localBuffer, + encJoinAcceptSize + JOIN_ACCEPT_MIC_COMPUTATION_OFFSET - + LORAMAC_MHDR_FIELD_SIZE - LORAMAC_MIC_FIELD_SIZE, + mic, J_S_INT_KEY ) != SECURE_ELEMENT_SUCCESS ) + { + return SECURE_ELEMENT_FAIL_CMAC; + } } - } #endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ - else - { - return SECURE_ELEMENT_ERROR_INVALID_LORAWAM_SPEC_VERSION; - } + else + { + return SECURE_ELEMENT_ERROR_INVALID_LORAWAM_SPEC_VERSION; + } - return SECURE_ELEMENT_SUCCESS; + return SECURE_ELEMENT_SUCCESS; } -SecureElementStatus_t SecureElementRandomNumber(uint32_t *randomNum) +SecureElementStatus_t SecureElementRandomNumber( uint32_t* randomNum ) { - if (randomNum == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } - *randomNum = Radio.Random( ); - return SECURE_ELEMENT_SUCCESS; + if( randomNum == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } + *randomNum = Radio.Random(); + return SECURE_ELEMENT_SUCCESS; } -SecureElementStatus_t SecureElementSetDevEui(uint8_t *devEui) +SecureElementStatus_t SecureElementSetDevEui( uint8_t* devEui ) { - if (devEui == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } - memcpy1(SeNvmCtx.DevEui, devEui, SE_EUI_SIZE); - SeNvmCtxChanged(); - return SECURE_ELEMENT_SUCCESS; + if( devEui == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } + memcpy1( SeNvm->DevEui, devEui, SE_EUI_SIZE ); + return SECURE_ELEMENT_SUCCESS; } -uint8_t *SecureElementGetDevEui(void) +uint8_t* SecureElementGetDevEui( void ) { - return SeNvmCtx.DevEui; + return SeNvm->DevEui; } -SecureElementStatus_t SecureElementSetJoinEui(uint8_t *joinEui) +SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui ) { - if (joinEui == NULL) - { - return SECURE_ELEMENT_ERROR_NPE; - } - memcpy1(SeNvmCtx.JoinEui, joinEui, SE_EUI_SIZE); - SeNvmCtxChanged(); - return SECURE_ELEMENT_SUCCESS; + if( joinEui == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } + memcpy1( SeNvm->JoinEui, joinEui, SE_EUI_SIZE ); + return SECURE_ELEMENT_SUCCESS; } -uint8_t *SecureElementGetJoinEui(void) +uint8_t* SecureElementGetJoinEui( void ) { - return SeNvmCtx.JoinEui; + return SeNvm->JoinEui; } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/LoRaWAN/LICENSE.txt b/Middlewares/Third_Party/LoRaWAN/LICENSE.txt deleted file mode 100644 index 51f599a9..00000000 --- a/Middlewares/Third_Party/LoRaWAN/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -Revised BSD License -Copyright Semtech Corporation 2013. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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. - * Neither the name of the Semtech corporation 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 SEMTECH CORPORATION 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. \ No newline at end of file diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.c index df9c5643..ac4dca98 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.c +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.c @@ -33,26 +33,31 @@ ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ -#include "secure-element.h" - -#include "LmHandler.h" +#include +#include +#include +#include "utilities.h" +#include "timer.h" +#include "Commissioning.h" +#include "NvmDataMgmt.h" +#include "radio.h" #include "Region.h" +#include "LoRaMacTest.h" +#include "LmHandler.h" +#include "LmhPackage.h" +#include "LmhpCompliance.h" +#include "secure-element.h" #include "mw_log_conf.h" /* needed for MW_LOG */ #include "lorawan_version.h" -#include "Commissioning.h" +#include "lora_info.h" #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) #else /* LORAWAN_KMS == 1 */ #include "kms.h" #include "kms_platf_objects_interface.h" #endif /* LORAWAN_KMS */ - -#include "NvmCtxMgmt.h" -#include "lora_info.h" -#include "LmhpCompliance.h" -#include "LoRaMacTest.h" #if (!defined (LORAWAN_DATA_DISTRIB_MGT) || (LORAWAN_DATA_DISTRIB_MGT == 0)) #else /* LORAWAN_DATA_DISTRIB_MGT == 1 */ -#include "LmhpDataDistribution.h" +#include "LmhpPackagesRegistration.h" #endif /* LORAWAN_DATA_DISTRIB_MGT */ /* Private typedef -----------------------------------------------------------*/ @@ -61,9 +66,9 @@ */ typedef enum PackageNotifyTypes_e { - PACKAGE_MCPS_CONFIRM, - PACKAGE_MCPS_INDICATION, - PACKAGE_MLME_CONFIRM, + PACKAGE_MCPS_CONFIRM, + PACKAGE_MCPS_INDICATION, + PACKAGE_MLME_CONFIRM } PackageNotifyTypes_t; /* Private define ------------------------------------------------------------*/ @@ -83,55 +88,162 @@ typedef enum PackageNotifyTypes_e */ #define HEX16(X) HEX8(X), X[8], X[9], X[10], X[11], X[12], X[13], X[14], X[15] +/* Private variables ---------------------------------------------------------*/ +static CommissioningParams_t CommissioningParams = +{ + .DevEui = { 0 }, // Automatically filed from secure-element + .JoinEui = { 0 }, // Automatically filed from secure-element + .NetworkId = LORAWAN_NETWORK_ID, + .DevAddr = LORAWAN_DEVICE_ADDRESS, +}; + +/*! + * LoRaWAN compliance tests handler parameters + */ +static LmhpComplianceParams_t LmhpComplianceParams = +{ + .AdrEnabled = LORAMAC_HANDLER_ADR_ON, + .DutyCycleEnabled = false, + .StopPeripherals = NULL, + .StartPeripherals = NULL, +}; + +static LmhPackage_t *LmHandlerPackages[PKG_MAX_NUMBER]; + +/*! + * Upper layer LoRaMac parameters + */ +static LmHandlerParams_t LmHandlerParams; + +/*! + * Upper layer callbacks + */ +static LmHandlerCallbacks_t *LmHandlerCallbacks; + +/*! + * Used to notify LmHandler of LoRaMac events + */ +static LoRaMacPrimitives_t LoRaMacPrimitives; + +/*! + * LoRaMac callbacks + */ +static LoRaMacCallback_t LoRaMacCallbacks; + +static LmHandlerJoinParams_t JoinParams = +{ + .Mode = ACTIVATION_TYPE_NONE, + .Datarate = DR_0, + .Status = LORAMAC_HANDLER_ERROR +}; + +static LmHandlerTxParams_t TxParams = +{ + .MsgType = LORAMAC_HANDLER_UNCONFIRMED_MSG, + .AckReceived = 0, + .Datarate = DR_0, + .UplinkCounter = 0, + .AppData = + { + .Port = 0, + .BufferSize = 0, + .Buffer = NULL + }, + .TxPower = TX_POWER_0, + .Channel = 0 +}; + +static LmHandlerRxParams_t RxParams = +{ + .Rssi = 0, + .Snr = 0, + .DownlinkCounter = 0, + .RxSlot = -1, + .LinkCheck = false, + .DemodMargin = 0, + .NbGateways = 0 +}; + +#if ( LORAMAC_CLASSB_ENABLED == 1 ) +static LmHandlerBeaconParams_t BeaconParams = +{ + .State = LORAMAC_HANDLER_BEACON_ACQUIRING, + .Info = + { + .Time = { .Seconds = 0, .SubSeconds = 0 }, + .Frequency = 0, + .Datarate = 0, + .Rssi = 0, + .Snr = 0, + .GwSpecific = + { + .InfoDesc = 0, + .Info = { 0 } + } + } +}; +#endif /* LORAMAC_CLASSB_ENABLED == 1 */ + +/*! + * Package Application buffer + */ +static uint8_t AppDataBuffer[LORAWAN_APP_DATA_BUFFER_MAX_SIZE]; + +/*! + * Package application data structure + */ +static LmHandlerAppData_t AppData = { 0, LORAWAN_APP_DATA_BUFFER_MAX_SIZE, AppDataBuffer }; + +#if ( LORAMAC_CLASSB_ENABLED == 1 ) +/*! + * Indicates if a switch to Class B operation is pending or not. + */ +static bool IsClassBSwitchPending = false; +#endif /* LORAMAC_CLASSB_ENABLED == 1 */ + +static bool CtxRestoreDone = false; + /* Private function prototypes -----------------------------------------------*/ /*! * \brief MCPS-Confirm event function * - * \param [IN] mcpsConfirm Pointer to the confirm structure, - * containing confirm attributes. + * \param [IN] mcpsConfirm - Pointer to the confirm structure, + * containing confirm attributes. */ -static void McpsConfirm(McpsConfirm_t *mcpsConfirm); +static void McpsConfirm( McpsConfirm_t *mcpsConfirm ); /*! * \brief MCPS-Indication event function * - * \param [IN] mcpsIndication Pointer to the indication structure, - * containing indication attributes. + * \param [IN] mcpsIndication - Pointer to the indication structure, + * containing indication attributes. */ -static void McpsIndication(McpsIndication_t *mcpsIndication); +static void McpsIndication( McpsIndication_t *mcpsIndication, LoRaMacRxStatus_t *RxStatus ); /*! * \brief MLME-Confirm event function * - * \param [IN] MlmeConfirm Pointer to the confirm structure, - * containing confirm attributes. + * \param [IN] MlmeConfirm - Pointer to the confirm structure, + * containing confirm attributes. */ -static void MlmeConfirm(MlmeConfirm_t *mlmeConfirm); +static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm ); /*! * \brief MLME-Indication event function * - * \param [IN] mlmeIndication Pointer to the indication structure, - * containing indication attributes. - */ -static void MlmeIndication(MlmeIndication_t *mlmeIndication); - -/*! - * \brief Requests network server time update - * - * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been - * processed else \ref LORAMAC_HANDLER_ERROR + * \param [IN] mlmeIndication - Pointer to the indication structure, + * containing indication attributes. */ -static LmHandlerErrorStatus_t LmHandlerDeviceTimeReq(void); +static void MlmeIndication( MlmeIndication_t *mlmeIndication, LoRaMacRxStatus_t *RxStatus ); #if ( LORAMAC_CLASSB_ENABLED == 1 ) /*! - * \brief Starts the beacon search + * Starts the beacon search * * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been * processed else \ref LORAMAC_HANDLER_ERROR */ -static LmHandlerErrorStatus_t LmHandlerBeaconReq(void); +static LmHandlerErrorStatus_t LmHandlerBeaconReq( void ); /*! * \brief Informs the server on the ping-slot periodicity to use @@ -146,16 +258,18 @@ static LmHandlerErrorStatus_t LmHandlerPingSlotReq(uint8_t periodicity); #endif /* LORAMAC_CLASSB_ENABLED == 1 */ /*! - * \brief Notifies the package to process the LoRaMac callbacks. + * Notifies the package to process the LoRaMac callbacks. * - * \param [IN] notifyType MAC notification type [PACKAGE_MCPS_CONFIRM, - * PACKAGE_MCPS_INDICATION, - * PACKAGE_MLME_CONFIRM, - * PACKAGE_MLME_INDICATION] - * \param [IN] params Notification parameters. The params type can be - * [McpsConfirm_t, McpsIndication_t, MlmeConfirm_t, MlmeIndication_t] + * \param [IN] notifyType MAC notification type [PACKAGE_MCPS_CONFIRM, + * PACKAGE_MCPS_INDICATION, + * PACKAGE_MLME_CONFIRM, + * PACKAGE_MLME_INDICATION] + * \param[IN] params Notification parameters. The params type can be + * [McpsConfirm_t, McpsIndication_t, MlmeConfirm_t, MlmeIndication_t] */ -static void LmHandlerPackagesNotify(PackageNotifyTypes_t notifyType, void *params); +static void LmHandlerPackagesNotify( PackageNotifyTypes_t notifyType, void *params ); + +static void LmHandlerPackagesProcess( void ); /*! * \brief Check if the package ID is initialized @@ -182,1463 +296,1643 @@ static void DisplayClassUpdate(DeviceClass_t deviceClass); static void DisplayBeaconUpdate(LmHandlerBeaconParams_t *params); #endif /* LORAMAC_CLASSB_ENABLED == 1 */ -/* Private variables ---------------------------------------------------------*/ -static CommissioningParams_t CommissioningParams = -{ - .DevEui = { 0 }, /* Automatically filed from secure-element */ - .JoinEui = { 0 }, /* Automatically filed from secure-element */ - .NetworkId = LORAWAN_NETWORK_ID, - .DevAddr = LORAWAN_DEVICE_ADDRESS, -}; - -/*! - * LoRaWAN compliance tests handler parameters - */ -static LmhpComplianceParams_t LmhpComplianceParams = -{ - .AdrEnabled = LORAMAC_HANDLER_ADR_ON, - .DutyCycleEnabled = false, - .StopPeripherals = NULL, - .StartPeripherals = NULL, -}; - -static LmhPackage_t *LmHandlerPackages[PKG_MAX_NUMBER]; - -/*! - * Upper layer LoRaMac parameters - */ -static LmHandlerParams_t LmHandlerParams; - -/*! - * Upper layer callbacks - */ -static LmHandlerCallbacks_t LmHandlerCallbacks; - -/*! - * Used to notify LmHandler of LoRaMac events - */ -static LoRaMacPrimitives_t LoRaMacPrimitives; - -/*! - * LoRaMac callbacks - */ -static LoRaMacCallback_t LoRaMacCallbacks; - -static LmHandlerJoinParams_t JoinParams = -{ - .Mode = ACTIVATION_TYPE_NONE, - .Datarate = DR_0, - .Status = LORAMAC_HANDLER_ERROR -}; - -static LmHandlerTxParams_t TxParams = -{ - .MsgType = LORAMAC_HANDLER_UNCONFIRMED_MSG, - .AckReceived = 0, - .Datarate = DR_0, - .UplinkCounter = 0, - .AppData = - { - .Port = 0, - .BufferSize = 0, - .Buffer = NULL - }, - .TxPower = TX_POWER_0, - .Channel = 0 -}; - -static LmHandlerRxParams_t RxParams = -{ - .Rssi = 0, - .Snr = 0, - .DownlinkCounter = 0, - .RxSlot = -1 -}; +static LmHandlerErrorStatus_t LmHandlerSetSystemMaxRxError( uint32_t maxErrorInMs ); -#if ( LORAMAC_CLASSB_ENABLED == 1 ) -static LmHandlerBeaconParams_t BeaconParams = +/* Exported functions ---------------------------------------------------------*/ +LmHandlerErrorStatus_t LmHandlerInit( LmHandlerCallbacks_t *handlerCallbacks ) { - .State = LORAMAC_HANDLER_BEACON_ACQUIRING, - .Info = - { - .Time = { .Seconds = 0, .SubSeconds = 0 }, - .Frequency = 0, - .Datarate = 0, - .Rssi = 0, - .Snr = 0, - .GwSpecific = + LmHandlerCallbacks = handlerCallbacks; + + LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; + LoRaMacPrimitives.MacMcpsIndication = McpsIndication; + LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; + LoRaMacPrimitives.MacMlmeIndication = MlmeIndication; + LoRaMacCallbacks.GetBatteryLevel = LmHandlerCallbacks->GetBatteryLevel; + LoRaMacCallbacks.GetTemperatureLevel = LmHandlerCallbacks->GetTemperature; + LoRaMacCallbacks.GetUniqueId = LmHandlerCallbacks->GetUniqueId; + LoRaMacCallbacks.NvmDataChange = NvmDataMgmtEvent; + LoRaMacCallbacks.MacProcessNotify = LmHandlerCallbacks->OnMacProcess; + + /*The LoRa-Alliance Compliance protocol package should always be initialized and activated.*/ + if (LmHandlerPackageRegister(PACKAGE_ID_COMPLIANCE, &LmhpComplianceParams) != LORAMAC_HANDLER_SUCCESS) { - .InfoDesc = 0, - .Info = { 0 } + return LORAMAC_HANDLER_ERROR; } - } -}; -#endif /* LORAMAC_CLASSB_ENABLED == 1 */ - -/*! - * Package Application buffer - */ -static uint8_t AppDataBuffer[LORAWAN_APP_DATA_BUFFER_MAX_SIZE]; - -/*! - * Package application data structure - */ -static LmHandlerAppData_t AppData = { 0, 0, AppDataBuffer }; - -#if ( LORAMAC_CLASSB_ENABLED == 1 ) -/*! - * Indicates if a switch to Class B operation is pending or not. - */ -static bool IsClassBSwitchPending = false; -#endif /* LORAMAC_CLASSB_ENABLED == 1 */ - -static bool CtxRestoreDone = false; - -/* Exported functions ---------------------------------------------------------*/ -LmHandlerErrorStatus_t LmHandlerInit(LmHandlerCallbacks_t *handlerCallbacks) -{ - UTIL_MEM_cpy_8((void *)&LmHandlerCallbacks, (const void *)handlerCallbacks, sizeof(LmHandlerCallbacks_t)); - - LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; - LoRaMacPrimitives.MacMcpsIndication = McpsIndication; - LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; - LoRaMacPrimitives.MacMlmeIndication = MlmeIndication; - LoRaMacCallbacks.GetBatteryLevel = LmHandlerCallbacks.GetBatteryLevel; - LoRaMacCallbacks.GetTemperatureLevel = LmHandlerCallbacks.GetTemperature; - LoRaMacCallbacks.NvmContextChange = NvmCtxMgmtEvent; - LoRaMacCallbacks.MacProcessNotify = LmHandlerCallbacks.OnMacProcess; - - /*The LoRa-Alliance Compliance protocol package should always be initialized and activated.*/ - if (LmHandlerPackageRegister(PACKAGE_ID_COMPLIANCE, &LmhpComplianceParams) != LORAMAC_HANDLER_SUCCESS) - { - return LORAMAC_HANDLER_ERROR; - } #if (!defined (LORAWAN_DATA_DISTRIB_MGT) || (LORAWAN_DATA_DISTRIB_MGT == 0)) #else /*LORAWAN_DATA_DISTRIB_MGT == 1*/ - if (LmhpDataDistributionInit() != LORAMAC_HANDLER_SUCCESS) - { - return LORAMAC_HANDLER_ERROR; - } + if (LmhpPackagesRegistrationInit() != LORAMAC_HANDLER_SUCCESS) + { + return LORAMAC_HANDLER_ERROR; + } #endif /*LORAWAN_DATA_DISTRIB_MGT*/ - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -LmHandlerErrorStatus_t LmHandlerConfigure(LmHandlerParams_t *handlerParams) +LmHandlerErrorStatus_t LmHandlerConfigure( LmHandlerParams_t *handlerParams ) { - MibRequestConfirm_t mibReq; - LoraInfo_t *loraInfo; + uint16_t nbNvmData = 0; + MibRequestConfirm_t mibReq; + LoraInfo_t *loraInfo; - UTIL_MEM_cpy_8((void *)&LmHandlerParams, (const void *)handlerParams, sizeof(LmHandlerParams_t)); + UTIL_MEM_cpy_8((void *)&LmHandlerParams, (const void *)handlerParams, sizeof(LmHandlerParams_t)); #if ( LORAMAC_CLASSB_ENABLED == 1 ) - IsClassBSwitchPending = false; + IsClassBSwitchPending = false; #endif /* LORAMAC_CLASSB_ENABLED == 1 */ - loraInfo = LoraInfo_GetPtr(); + loraInfo = LoraInfo_GetPtr(); - if (0U != ((1 << (LmHandlerParams.ActiveRegion)) & (loraInfo->Region))) - { - if (LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, LmHandlerParams.ActiveRegion) != LORAMAC_STATUS_OK) + if (0U != ((1 << (LmHandlerParams.ActiveRegion)) & (loraInfo->Region))) + { + if (LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, LmHandlerParams.ActiveRegion) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + } + else { - return LORAMAC_HANDLER_ERROR; + MW_LOG(TS_ON, VLEVEL_ALWAYS, "error: Region is not defined in the MW: set lorawan_conf.h accordingly\r\n"); + while (1) {} /* error: Region is not defined in the MW */ } - } - else - { - MW_LOG(TS_ON, VLEVEL_ALWAYS, "error: Region is not defined in the MW: set lorawan_conf.h accordingly\r\n"); - while (1) {} /* error: Region is not defined in the MW */ - } - /* Try to restore from NVM and query the mac if possible. */ - if (NvmCtxMgmtRestore() == NVMCTXMGMT_STATUS_SUCCESS) - { - CtxRestoreDone = true; - } - else - { - CtxRestoreDone = false; + // Restore data if required + nbNvmData = NvmDataMgmtRestore( ); -#if (defined (LORAWAN_KMS) && (LORAWAN_KMS == 1)) - SecureElementSetObjHandler(APP_KEY, KMS_APP_KEY_OBJECT_HANDLE); - SecureElementSetObjHandler(NWK_KEY, KMS_NWK_KEY_OBJECT_HANDLE); -#if ( LORAMAC_CLASSB_ENABLED == 1 ) - SecureElementSetObjHandler(SLOT_RAND_ZERO_KEY, KMS_ZERO_KEY_OBJECT_HANDLE); -#endif /* LORAMAC_CLASSB_ENABLED */ -#endif /* LORAWAN_KMS == 1 */ - /* Read secure-element DEV_EUI and JOIN_EUI values. */ + // Try to restore from NVM and query the mac if possible. + if( nbNvmData > 0 ) + { + CtxRestoreDone = true; + } + else + { + CtxRestoreDone = false; + } + + // Read secure-element DEV_EUI and JOIN_EUI values. mibReq.Type = MIB_DEV_EUI; - LoRaMacMibGetRequestConfirm(&mibReq); - memcpy1(CommissioningParams.DevEui, mibReq.Param.DevEui, 8); + LoRaMacMibGetRequestConfirm( &mibReq ); + memcpy1( CommissioningParams.DevEui, mibReq.Param.DevEui, 8 ); mibReq.Type = MIB_JOIN_EUI; - LoRaMacMibGetRequestConfirm(&mibReq); - memcpy1(CommissioningParams.JoinEui, mibReq.Param.JoinEui, 8); - } - MW_LOG(TS_OFF, VLEVEL_M, "###### DevEui: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\r\n", - HEX8(CommissioningParams.DevEui)); - MW_LOG(TS_OFF, VLEVEL_M, "###### AppEui: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\r\n", - HEX8(CommissioningParams.JoinEui)); -#if (defined (LORAWAN_KMS) && (LORAWAN_KMS == 1)) - MW_LOG(TS_OFF, VLEVEL_L, "###### KMS ENABLED \r\n"); -#endif /* LORAWAN_KMS == 1 */ + LoRaMacMibGetRequestConfirm( &mibReq ); + memcpy1( CommissioningParams.JoinEui, mibReq.Param.JoinEui, 8 ); + +#if ( STATIC_DEVICE_ADDRESS != 1 ) + CommissioningParams.DevAddr = LmHandlerCallbacks->GetDevAddr(); +#endif /* STATIC_DEVICE_ADDRESS != 1 */ - mibReq.Type = MIB_PUBLIC_NETWORK; - mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; - LoRaMacMibSetRequestConfirm(&mibReq); + mibReq.Type = MIB_DEV_ADDR; + mibReq.Param.DevAddr = CommissioningParams.DevAddr; + LoRaMacMibSetRequestConfirm(&mibReq); - mibReq.Type = MIB_REPEATER_SUPPORT; - mibReq.Param.EnableRepeaterSupport = LORAWAN_REPEATER_SUPPORT; - LoRaMacMibSetRequestConfirm(&mibReq); + MW_LOG(TS_OFF, VLEVEL_M, "###### DevEui: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", + HEX8(CommissioningParams.DevEui)); + MW_LOG(TS_OFF, VLEVEL_M, "###### AppEui: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", + HEX8(CommissioningParams.JoinEui)); + MW_LOG(TS_OFF, VLEVEL_M, "###### DevAddr: %02X:%02X:%02X:%02X\r\n", + (unsigned)((unsigned char *)(&CommissioningParams.DevAddr))[3], + (unsigned)((unsigned char *)(&CommissioningParams.DevAddr))[2], + (unsigned)((unsigned char *)(&CommissioningParams.DevAddr))[1], + (unsigned)((unsigned char *)(&CommissioningParams.DevAddr))[0]); - mibReq.Type = MIB_ADR; - mibReq.Param.AdrEnable = LmHandlerParams.AdrEnable; - LoRaMacMibSetRequestConfirm(&mibReq); +#if (defined (LORAWAN_KMS) && (LORAWAN_KMS == 1)) + MW_LOG(TS_OFF, VLEVEL_L, "###### KMS ENABLED \r\n"); +#endif /* LORAWAN_KMS == 1 */ - mibReq.Type = MIB_SYSTEM_MAX_RX_ERROR; - mibReq.Param.SystemMaxRxError = 20; - LoRaMacMibSetRequestConfirm(&mibReq); + mibReq.Type = MIB_PUBLIC_NETWORK; + mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; + LoRaMacMibSetRequestConfirm(&mibReq); - GetPhyParams_t getPhy; - PhyParam_t phyParam; - getPhy.Attribute = PHY_DUTY_CYCLE; - phyParam = RegionGetPhyParam(LmHandlerParams.ActiveRegion, &getPhy); - LmHandlerParams.DutyCycleEnabled = (bool) phyParam.Value; + mibReq.Type = MIB_NET_ID; + mibReq.Param.NetID = LORAWAN_NETWORK_ID; + LoRaMacMibSetRequestConfirm(&mibReq); - /* override previous value if reconfigure new region */ - LoRaMacTestSetDutyCycleOn(LmHandlerParams.DutyCycleEnabled); + mibReq.Type = MIB_REPEATER_SUPPORT; + mibReq.Param.EnableRepeaterSupport = LORAWAN_REPEATER_SUPPORT; + LoRaMacMibSetRequestConfirm( &mibReq ); - return LORAMAC_HANDLER_SUCCESS; -} + mibReq.Type = MIB_ADR; + mibReq.Param.AdrEnable = LmHandlerParams.AdrEnable; + LoRaMacMibSetRequestConfirm( &mibReq ); -bool LmHandlerIsBusy(void) -{ - if (LoRaMacIsBusy() == true) - { - return true; - } + GetPhyParams_t getPhy; + PhyParam_t phyParam; + getPhy.Attribute = PHY_DUTY_CYCLE; + phyParam = RegionGetPhyParam( LmHandlerParams.ActiveRegion, &getPhy ); + LmHandlerParams.DutyCycleEnabled = (bool) phyParam.Value; - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - /* The network isn't yet joined, try again later. */ - LmHandlerJoin(JoinParams.Mode); - return true; - } + LmHandlerSetSystemMaxRxError( 20 ); - if (LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->IsRunning() == true) - { - return true; - } - return false; + /* override previous value if reconfigure new region */ + LoRaMacTestSetDutyCycleOn( LmHandlerParams.DutyCycleEnabled ); + + return LORAMAC_HANDLER_SUCCESS; } -void LmHandlerProcess(void) +bool LmHandlerIsBusy( void ) { - /* Call at first the LoRaMAC process before to run all package process features */ - /* Processes the LoRaMac events */ - LoRaMacProcess(); - - /* Call all packages process functions */ - for (int8_t i = 0; i < PKG_MAX_NUMBER; i++) - { - if ((LmHandlerPackages[i] != NULL) && - (LmHandlerPackages[i]->Process != NULL) && - (LmHandlerPackageIsInitialized(i) != false)) + if( LoRaMacIsBusy( ) == true ) + { + return true; + } + if( LmHandlerJoinStatus( ) != LORAMAC_HANDLER_SET ) { - LmHandlerPackages[i]->Process(); + // The network isn't yet joined, try again later. + LmHandlerJoin( JoinParams.Mode ); + return true; } - } - NvmCtxMgmtStore(); + if( LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->IsRunning( ) == true ) + { + return true; + } + return false; } -LmHandlerFlagStatus_t LmHandlerJoinStatus(void) +void LmHandlerProcess( void ) { - MibRequestConfirm_t mibReq; - LoRaMacStatus_t status; + /* Call at first the LoRaMAC process before to run all package process features */ + // Processes the LoRaMac events + LoRaMacProcess( ); - mibReq.Type = MIB_NETWORK_ACTIVATION; - status = LoRaMacMibGetRequestConfirm(&mibReq); + // Call all packages process functions + LmHandlerPackagesProcess( ); - if (status == LORAMAC_STATUS_OK) - { - if (mibReq.Param.NetworkActivation == ACTIVATION_TYPE_NONE) - { - return LORAMAC_HANDLER_RESET; - } - else - { - return LORAMAC_HANDLER_SET; - } - } - else - { - return LORAMAC_HANDLER_RESET; - } + // Store to NVM if required + NvmDataMgmtStore( ); } -void LmHandlerJoin(ActivationType_t mode) +void LmHandlerJoin( ActivationType_t mode ) { - MibRequestConfirm_t mibReq; + MibRequestConfirm_t mibReq; #if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) #else /* LORAWAN_KMS == 1 */ #if (OVER_THE_AIR_ACTIVATION == 0) - if (mode == ACTIVATION_TYPE_OTAA) - { - MW_LOG(TS_OFF, VLEVEL_M, "ERROR: OTAA mode not implemented\r\n"); - while (1); - } + if ( mode == ACTIVATION_TYPE_OTAA ) + { + MW_LOG(TS_OFF, VLEVEL_M, "ERROR: OTAA mode not implemented\r\n"); + while (1); + } #endif /* OVER_THE_AIR_ACTIVATION */ -#if (ACTIVATION_BY_PERSONALISATION == 0) - if (mode == ACTIVATION_TYPE_ABP) - { - MW_LOG(TS_OFF, VLEVEL_M, "ERROR: ABP mode not implemented\r\n"); - while (1); - } -#endif /* ACTIVATION_BY_PERSONALISATION */ - SecureElementDeleteDerivedKeys(NULL); +#if (ACTIVATION_BY_PERSONALIZATION == 0) + if ( mode == ACTIVATION_TYPE_ABP ) + { + MW_LOG(TS_OFF, VLEVEL_M, "ERROR: ABP mode not implemented\r\n"); + while (1); + } +#endif /* ACTIVATION_BY_PERSONALIZATION */ #endif /* LORAWAN_KMS */ - if (mode == ACTIVATION_TYPE_OTAA) - { - MlmeReq_t mlmeReq; - JoinParams.Mode = ACTIVATION_TYPE_OTAA; - - LoRaMacStart(); + if ( mode == ACTIVATION_TYPE_OTAA ) + { + MlmeReq_t mlmeReq; + JoinParams.Mode = ACTIVATION_TYPE_OTAA; - /* Starts the OTAA join procedure */ - mlmeReq.Type = MLME_JOIN; - mlmeReq.Req.Join.Datarate = LmHandlerParams.TxDatarate; - LoRaMacMlmeRequest(&mlmeReq); + LoRaMacStart(); - } - else - { - JoinParams.Mode = ACTIVATION_TYPE_ABP; - JoinParams.Status = LORAMAC_HANDLER_SUCCESS; + mlmeReq.Type = MLME_JOIN; + mlmeReq.Req.Join.Datarate = LmHandlerParams.TxDatarate; - if (CtxRestoreDone == false) + // Starts the OTAA join procedure + LoRaMacMlmeRequest( &mlmeReq ); + } + else { - /* Tell the MAC layer which network server version are we connecting too. */ - mibReq.Type = MIB_ABP_LORAWAN_VERSION; - mibReq.Param.AbpLrWanVersion.Value = ABP_ACTIVATION_LRWAN_VERSION; - LoRaMacMibSetRequestConfirm(&mibReq); - - mibReq.Type = MIB_NET_ID; - mibReq.Param.NetID = CommissioningParams.NetworkId; - LoRaMacMibSetRequestConfirm(&mibReq); - -#if ( STATIC_DEVICE_ADDRESS != 1 ) - CommissioningParams.DevAddr = GetDevAddr(); -#endif /* STATIC_DEVICE_ADDRESS != 1 */ + JoinParams.Mode = ACTIVATION_TYPE_ABP; + JoinParams.Datarate = LmHandlerParams.TxDatarate; + JoinParams.Status = LORAMAC_HANDLER_SUCCESS; - mibReq.Type = MIB_DEV_ADDR; - mibReq.Param.DevAddr = CommissioningParams.DevAddr; - LoRaMacMibSetRequestConfirm(&mibReq); - MW_LOG(TS_OFF, VLEVEL_M, "###### DevAddr: %08X\r\n", CommissioningParams.DevAddr); + if (CtxRestoreDone == false) + { + /* Tell the MAC layer which network server version are we connecting too. */ + mibReq.Type = MIB_ABP_LORAWAN_VERSION; + mibReq.Param.AbpLrWanVersion.Value = ABP_ACTIVATION_LRWAN_VERSION; + LoRaMacMibSetRequestConfirm(&mibReq); #if (defined (LORAWAN_KMS) && (LORAWAN_KMS == 1)) #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - SecureElementSetObjHandler(F_NWK_S_INT_KEY, KMS_F_NWK_S_INT_KEY_OBJECT_HANDLE); - SecureElementSetObjHandler(S_NWK_S_INT_KEY, KMS_S_NWK_S_INT_KEY_OBJECT_HANDLE); - SecureElementSetObjHandler(NWK_S_ENC_KEY, KMS_NWK_S_ENC_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(F_NWK_S_INT_KEY, KMS_F_NWK_S_INT_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(S_NWK_S_INT_KEY, KMS_S_NWK_S_INT_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(NWK_S_ENC_KEY, KMS_NWK_S_ENC_KEY_OBJECT_HANDLE); #else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ - SecureElementSetObjHandler(NWK_S_KEY, KMS_NWK_S_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(NWK_S_KEY, KMS_NWK_S_KEY_OBJECT_HANDLE); #endif /* USE_LRWAN_1_1_X_CRYPTO */ - SecureElementSetObjHandler(APP_S_KEY, KMS_APP_S_KEY_OBJECT_HANDLE); + SecureElementSetObjHandler(APP_S_KEY, KMS_APP_S_KEY_OBJECT_HANDLE); #endif /* LORAWAN_KMS == 1 */ - } + } - LoRaMacStart(); - mibReq.Type = MIB_NETWORK_ACTIVATION; - mibReq.Param.NetworkActivation = ACTIVATION_TYPE_ABP; - LoRaMacMibSetRequestConfirm(&mibReq); + LoRaMacStart(); + mibReq.Type = MIB_NETWORK_ACTIVATION; + mibReq.Param.NetworkActivation = ACTIVATION_TYPE_ABP; + LoRaMacMibSetRequestConfirm( &mibReq ); - LmHandlerCallbacks.OnJoinRequest(&JoinParams); - LmHandlerRequestClass(LmHandlerParams.DefaultClass); - } + // Notify upper layer + LmHandlerCallbacks->OnJoinRequest( &JoinParams ); + LmHandlerRequestClass(LmHandlerParams.DefaultClass); + } } -LmHandlerErrorStatus_t LmHandlerStop(void) +LmHandlerFlagStatus_t LmHandlerJoinStatus( void ) { - if (LoRaMacDeInitialization() == LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_SUCCESS; - } - else - { - return LORAMAC_HANDLER_BUSY_ERROR; - } -} - -LmHandlerErrorStatus_t LmHandlerSend(LmHandlerAppData_t *appData, LmHandlerMsgTypes_t isTxConfirmed, - TimerTime_t *nextTxIn, bool allowDelayedTx) -{ - LoRaMacStatus_t status; - LmHandlerErrorStatus_t lmhStatus = LORAMAC_HANDLER_ERROR; - McpsReq_t mcpsReq; - LoRaMacTxInfo_t txInfo; - - if (LoRaMacIsBusy() == true) - { - return LORAMAC_HANDLER_BUSY_ERROR; - } - - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - /* The network isn't yet joined, try again later. */ - LmHandlerJoin(JoinParams.Mode); - return LORAMAC_HANDLER_NO_NETWORK_JOINED; - } - - if ((LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->IsRunning() == true) - && (appData->Port != LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->Port) && (appData->Port != 0)) - { - return LORAMAC_HANDLER_COMPLIANCE_RUNNING; - } - - mcpsReq.Req.Unconfirmed.Datarate = LmHandlerParams.TxDatarate; - if (LoRaMacQueryTxPossible(appData->BufferSize, &txInfo) != LORAMAC_STATUS_OK) - { - /* Send empty frame in order to flush MAC commands */ - TxParams.MsgType = LORAMAC_HANDLER_UNCONFIRMED_MSG; - mcpsReq.Type = MCPS_UNCONFIRMED; - mcpsReq.Req.Unconfirmed.fBuffer = NULL; - mcpsReq.Req.Unconfirmed.fBufferSize = 0; - } - else - { - TxParams.MsgType = isTxConfirmed; - mcpsReq.Req.Unconfirmed.fPort = appData->Port; - mcpsReq.Req.Unconfirmed.fBufferSize = appData->BufferSize; - mcpsReq.Req.Unconfirmed.fBuffer = appData->Buffer; - if (isTxConfirmed == LORAMAC_HANDLER_UNCONFIRMED_MSG) - { - mcpsReq.Type = MCPS_UNCONFIRMED; - } - else - { - mcpsReq.Type = MCPS_CONFIRMED; - mcpsReq.Req.Confirmed.NbTrials = 8; - } - } - - TxParams.AppData = *appData; - TxParams.Datarate = LmHandlerParams.TxDatarate; - - status = LoRaMacMcpsRequest(&mcpsReq, allowDelayedTx); - if (nextTxIn != NULL) - { - *nextTxIn = mcpsReq.ReqReturn.DutyCycleWaitTime; - } - - switch(status) - { - case LORAMAC_STATUS_OK: - lmhStatus = LORAMAC_HANDLER_SUCCESS; - break; - case LORAMAC_STATUS_BUSY: - case LORAMAC_STATUS_BUSY_UPLINK_COLLISION: - case LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME: - case LORAMAC_STATUS_BUSY_PING_SLOT_WINDOW_TIME: - lmhStatus = LORAMAC_HANDLER_BUSY_ERROR; - break; - case LORAMAC_STATUS_NO_NETWORK_JOINED: - lmhStatus = LORAMAC_HANDLER_NO_NETWORK_JOINED; - break; - case LORAMAC_STATUS_CRYPTO_ERROR: - lmhStatus = LORAMAC_HANDLER_CRYPTO_ERROR; - break; - case LORAMAC_STATUS_DUTYCYCLE_RESTRICTED: - lmhStatus = LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED; - break; - case LORAMAC_STATUS_SERVICE_UNKNOWN: - case LORAMAC_STATUS_PARAMETER_INVALID: - case LORAMAC_STATUS_MAC_COMMAD_ERROR: - case LORAMAC_STATUS_FCNT_HANDLER_ERROR: - case LORAMAC_STATUS_REGION_NOT_SUPPORTED: - case LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND: - case LORAMAC_STATUS_NO_CHANNEL_FOUND: - case LORAMAC_STATUS_LENGTH_ERROR: - default: - lmhStatus = LORAMAC_HANDLER_ERROR; - break; - } - - return lmhStatus; -} - -LmHandlerErrorStatus_t LmHandlerRequestClass(DeviceClass_t newClass) -{ - MibRequestConfirm_t mibReq; - DeviceClass_t currentClass; - LmHandlerErrorStatus_t errorStatus = LORAMAC_HANDLER_SUCCESS; - - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - return LORAMAC_HANDLER_NO_NETWORK_JOINED; - } - - mibReq.Type = MIB_DEVICE_CLASS; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } - currentClass = mibReq.Param.Class; + MibRequestConfirm_t mibReq; + LoRaMacStatus_t status; - /* Attempt to switch only if class update */ - if (currentClass != newClass) - { - switch (newClass) + mibReq.Type = MIB_NETWORK_ACTIVATION; + status = LoRaMacMibGetRequestConfirm( &mibReq ); + + if( status == LORAMAC_STATUS_OK ) { - case CLASS_A: - { - if (currentClass != CLASS_A) - { - mibReq.Param.Class = CLASS_A; - if (LoRaMacMibSetRequestConfirm(&mibReq) == LORAMAC_STATUS_OK) - { - /* Switch is instantaneous */ - DisplayClassUpdate(CLASS_A); - } - else - { - errorStatus = LORAMAC_HANDLER_ERROR; - } - } - } - break; - case CLASS_B: - { -#if ( LORAMAC_CLASSB_ENABLED == 1 ) - if (currentClass != CLASS_A) - { - errorStatus = LORAMAC_HANDLER_ERROR; - } - else + if( mibReq.Param.NetworkActivation == ACTIVATION_TYPE_NONE ) { - /* Beacon must first be acquired */ - errorStatus = LmHandlerDeviceTimeReq(); - IsClassBSwitchPending = true; - } -#else /* LORAMAC_CLASSB_ENABLED == 0 */ - errorStatus = LORAMAC_HANDLER_ERROR; -#endif /* LORAMAC_CLASSB_ENABLED */ - } - break; - case CLASS_C: - { - if (currentClass != CLASS_A) - { - errorStatus = LORAMAC_HANDLER_ERROR; + return LORAMAC_HANDLER_RESET; } else { - /* Switch is instantaneous */ - mibReq.Param.Class = CLASS_C; - if (LoRaMacMibSetRequestConfirm(&mibReq) == LORAMAC_STATUS_OK) - { - DisplayClassUpdate(CLASS_C); - } - else - { - errorStatus = LORAMAC_HANDLER_ERROR; - } + return LORAMAC_HANDLER_SET; } - } - break; - default: - break; } - } - return errorStatus; + else + { + return LORAMAC_HANDLER_RESET; + } } -LmHandlerErrorStatus_t LmHandlerPackageRegister(uint8_t id, void *params) +LmHandlerErrorStatus_t LmHandlerStop(void) { - LmhPackage_t *package = NULL; - switch (id) - { - case PACKAGE_ID_COMPLIANCE: + if (LoRaMacDeInitialization() == LORAMAC_STATUS_OK) { - package = LmphCompliancePackageFactory(); - break; + return LORAMAC_HANDLER_SUCCESS; + } + else + { + return LORAMAC_HANDLER_BUSY_ERROR; + } +} + +LmHandlerErrorStatus_t LmHandlerSend( LmHandlerAppData_t *appData, LmHandlerMsgTypes_t isTxConfirmed, + TimerTime_t *nextTxIn, bool allowDelayedTx ) +{ + LoRaMacStatus_t status; + LmHandlerErrorStatus_t lmhStatus = LORAMAC_HANDLER_ERROR; + McpsReq_t mcpsReq; + LoRaMacTxInfo_t txInfo; + + if (LoRaMacIsBusy() == true) + { + return LORAMAC_HANDLER_BUSY_ERROR; + } + + if( LmHandlerJoinStatus( ) != LORAMAC_HANDLER_SET ) + { + // The network isn't joined, try again. + LmHandlerJoin(JoinParams.Mode); + return LORAMAC_HANDLER_NO_NETWORK_JOINED; + } + + if( ( LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->IsRunning( ) == true ) && ( appData->Port != LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->Port ) && ( appData->Port != 0 ) ) + { + return LORAMAC_HANDLER_COMPLIANCE_RUNNING; + } + + mcpsReq.Req.Unconfirmed.Datarate = LmHandlerParams.TxDatarate; + if( LoRaMacQueryTxPossible( appData->BufferSize, &txInfo ) != LORAMAC_STATUS_OK ) + { + // Send empty frame in order to flush MAC commands + TxParams.MsgType = LORAMAC_HANDLER_UNCONFIRMED_MSG; + mcpsReq.Type = MCPS_UNCONFIRMED; + mcpsReq.Req.Unconfirmed.fBuffer = NULL; + mcpsReq.Req.Unconfirmed.fBufferSize = 0; + } + else + { + TxParams.MsgType = isTxConfirmed; + mcpsReq.Req.Unconfirmed.fPort = appData->Port; + mcpsReq.Req.Unconfirmed.fBufferSize = appData->BufferSize; + mcpsReq.Req.Unconfirmed.fBuffer = appData->Buffer; + if( isTxConfirmed == LORAMAC_HANDLER_UNCONFIRMED_MSG ) + { + mcpsReq.Type = MCPS_UNCONFIRMED; + } + else + { + mcpsReq.Type = MCPS_CONFIRMED; + mcpsReq.Req.Confirmed.NbTrials = 8; + } + } + + TxParams.AppData = *appData; + TxParams.Datarate = LmHandlerParams.TxDatarate; + + status = LoRaMacMcpsRequest(&mcpsReq, allowDelayedTx); + if (nextTxIn != NULL) + { + *nextTxIn = mcpsReq.ReqReturn.DutyCycleWaitTime; + } + + switch (status) + { + case LORAMAC_STATUS_OK: + lmhStatus = LORAMAC_HANDLER_SUCCESS; + break; + case LORAMAC_STATUS_BUSY: + case LORAMAC_STATUS_BUSY_UPLINK_COLLISION: + case LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME: + case LORAMAC_STATUS_BUSY_PING_SLOT_WINDOW_TIME: + lmhStatus = LORAMAC_HANDLER_BUSY_ERROR; + break; + case LORAMAC_STATUS_NO_NETWORK_JOINED: + lmhStatus = LORAMAC_HANDLER_NO_NETWORK_JOINED; + break; + case LORAMAC_STATUS_CRYPTO_ERROR: + lmhStatus = LORAMAC_HANDLER_CRYPTO_ERROR; + break; + case LORAMAC_STATUS_DUTYCYCLE_RESTRICTED: + lmhStatus = LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED; + break; + case LORAMAC_STATUS_SERVICE_UNKNOWN: + case LORAMAC_STATUS_PARAMETER_INVALID: + case LORAMAC_STATUS_MAC_COMMAD_ERROR: + case LORAMAC_STATUS_FCNT_HANDLER_ERROR: + case LORAMAC_STATUS_REGION_NOT_SUPPORTED: + case LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND: + case LORAMAC_STATUS_NO_CHANNEL_FOUND: + case LORAMAC_STATUS_LENGTH_ERROR: + default: + lmhStatus = LORAMAC_HANDLER_ERROR; + break; } - default: -#if (!defined (LORAWAN_DATA_DISTRIB_MGT) || (LORAWAN_DATA_DISTRIB_MGT == 0)) -#else /*LORAWAN_DATA_DISTRIB_MGT == 1*/ - LmhpDataDistributionPackageRegister(id, &package); -#endif /*LORAWAN_DATA_DISTRIB_MGT*/ - break; - } - if (package != NULL) - { - LmHandlerPackages[id] = package; - LmHandlerPackages[id]->OnJoinRequest = LmHandlerJoin; - LmHandlerPackages[id]->OnSendRequest = LmHandlerSend; - LmHandlerPackages[id]->OnDeviceTimeRequest = LmHandlerDeviceTimeReq; - LmHandlerPackages[id]->Init(params, AppData.Buffer, LORAWAN_APP_DATA_BUFFER_MAX_SIZE); + return lmhStatus; +} + +LmHandlerErrorStatus_t LmHandlerLinkCheckReq( void ) +{ + LoRaMacStatus_t status; + MlmeReq_t mlmeReq; + + mlmeReq.Type = MLME_LINK_CHECK; + + status = LoRaMacMlmeRequest( &mlmeReq ); + + if( status == LORAMAC_STATUS_OK ) + { + return LORAMAC_HANDLER_SUCCESS; + } + else + { + return LORAMAC_HANDLER_ERROR; + } +} + +LmHandlerErrorStatus_t LmHandlerDeviceTimeReq( void ) +{ + LoRaMacStatus_t status; + MlmeReq_t mlmeReq; + + mlmeReq.Type = MLME_DEVICE_TIME; + + status = LoRaMacMlmeRequest( &mlmeReq ); + + if( status == LORAMAC_STATUS_OK ) + { + return LORAMAC_HANDLER_SUCCESS; + } + else + { + return LORAMAC_HANDLER_ERROR; + } +} + +#if ( LORAMAC_CLASSB_ENABLED == 1 ) +static LmHandlerErrorStatus_t LmHandlerBeaconReq( void ) +{ + LoRaMacStatus_t status; + MlmeReq_t mlmeReq; + + mlmeReq.Type = MLME_BEACON_ACQUISITION; + + status = LoRaMacMlmeRequest( &mlmeReq ); + + if( status == LORAMAC_STATUS_OK ) + { + return LORAMAC_HANDLER_SUCCESS; + } + else + { + return LORAMAC_HANDLER_ERROR; + } +} +static LmHandlerErrorStatus_t LmHandlerPingSlotReq( uint8_t periodicity ) +{ + LoRaMacStatus_t status; + MlmeReq_t mlmeReq; + + mlmeReq.Type = MLME_PING_SLOT_INFO; + mlmeReq.Req.PingSlotInfo.PingSlot.Fields.Periodicity = periodicity; + mlmeReq.Req.PingSlotInfo.PingSlot.Fields.RFU = 0; + + status = LoRaMacMlmeRequest( &mlmeReq ); + + if( status == LORAMAC_STATUS_OK ) + { + LmHandlerParams.PingPeriodicity = periodicity; + // Send an empty message + LmHandlerAppData_t appData = + { + .Buffer = NULL, + .BufferSize = 0, + .Port = 0 + }; + return LmHandlerSend( &appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, false ); + } + else + { + return LORAMAC_HANDLER_ERROR; + } +} +#endif /* LORAMAC_CLASSB_ENABLED == 1 */ + +LmHandlerErrorStatus_t LmHandlerRequestClass( DeviceClass_t newClass ) +{ + MibRequestConfirm_t mibReq; + DeviceClass_t currentClass; + LmHandlerErrorStatus_t errorStatus = LORAMAC_HANDLER_SUCCESS; + + if (LoRaMacIsBusy() == true) + { + return LORAMAC_HANDLER_BUSY_ERROR; + } + + if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) + { + return LORAMAC_HANDLER_NO_NETWORK_JOINED; + } + + mibReq.Type = MIB_DEVICE_CLASS; + if ( LoRaMacMibGetRequestConfirm( &mibReq ) != LORAMAC_STATUS_OK ) + { + return LORAMAC_HANDLER_ERROR; + } + currentClass = mibReq.Param.Class; + + // Attempt to switch only if class update + if( currentClass != newClass ) + { + switch( newClass ) + { + case CLASS_A: + { + if( currentClass != CLASS_A ) + { + mibReq.Param.Class = newClass; + if( LoRaMacMibSetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK ) + { + // Switch is instantaneous + DisplayClassUpdate(newClass); + if (LmHandlerCallbacks->OnClassChange != NULL) + { + LmHandlerCallbacks->OnClassChange( newClass ); + } + } + else + { + errorStatus = LORAMAC_HANDLER_ERROR; + } + } + } + break; + case CLASS_B: + { +#if ( LORAMAC_CLASSB_ENABLED == 1 ) + if( currentClass != CLASS_A ) + { + errorStatus = LORAMAC_HANDLER_ERROR; + } + else + { + // Beacon must first be acquired + errorStatus = LmHandlerDeviceTimeReq( ); + IsClassBSwitchPending = true; + } +#else /* LORAMAC_CLASSB_ENABLED == 0 */ + errorStatus = LORAMAC_HANDLER_ERROR; +#endif /* LORAMAC_CLASSB_ENABLED */ + } + break; + case CLASS_C: + { + if( currentClass != CLASS_A ) + { + errorStatus = LORAMAC_HANDLER_ERROR; + } + else + { + // Switch is instantaneous + mibReq.Param.Class = newClass; + if (LoRaMacMibSetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK) + { + DisplayClassUpdate(newClass); + if (LmHandlerCallbacks->OnClassChange != NULL) + { + LmHandlerCallbacks->OnClassChange( newClass ); + } + } + else + { + errorStatus = LORAMAC_HANDLER_ERROR; + } + } + } + break; + default: + break; + } + } + return errorStatus; +} + +LmHandlerErrorStatus_t LmHandlerGetCurrentClass( DeviceClass_t *deviceClass ) +{ + MibRequestConfirm_t mibReq; + if (deviceClass == NULL) + { + return LORAMAC_HANDLER_ERROR; + } + + mibReq.Type = MIB_DEVICE_CLASS; + if (LoRaMacMibGetRequestConfirm( &mibReq ) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + + *deviceClass = mibReq.Param.Class; return LORAMAC_HANDLER_SUCCESS; - } - else - { - return LORAMAC_HANDLER_ERROR; - } } -int32_t LmHandlerGetCurrentClass(DeviceClass_t *deviceClass) +LmHandlerErrorStatus_t LmHandlerGetTxDatarate( int8_t *txDatarate ) { - MibRequestConfirm_t mibReq; - if (deviceClass == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibGet; + if (txDatarate == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - mibReq.Type = MIB_DEVICE_CLASS; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibGet.Type = MIB_CHANNELS_DATARATE; + if (LoRaMacMibGetRequestConfirm( &mibGet ) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - *deviceClass = mibReq.Param.Class; - return LORAMAC_HANDLER_SUCCESS; + *txDatarate = mibGet.Param.ChannelsDatarate; + LmHandlerParams.TxDatarate = *txDatarate; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetTxDatarate(int8_t *txDatarate) +LmHandlerErrorStatus_t LmHandlerGetActiveRegion( LoRaMacRegion_t *region ) { - MibRequestConfirm_t mibGet; - if (txDatarate == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + if (region == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - mibGet.Type = MIB_CHANNELS_DATARATE; - if (LoRaMacMibGetRequestConfirm(&mibGet) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + *region = LmHandlerParams.ActiveRegion; + return LORAMAC_HANDLER_SUCCESS; +} + +static LmHandlerErrorStatus_t LmHandlerSetSystemMaxRxError( uint32_t maxErrorInMs ) +{ + MibRequestConfirm_t mibReq; - *txDatarate = mibGet.Param.ChannelsDatarate; - LmHandlerParams.TxDatarate = mibGet.Param.ChannelsDatarate; - return LORAMAC_HANDLER_SUCCESS; + mibReq.Type = MIB_SYSTEM_MAX_RX_ERROR; + mibReq.Param.SystemMaxRxError = maxErrorInMs; + if( LoRaMacMibSetRequestConfirm( &mibReq ) != LORAMAC_STATUS_OK ) + { + return LORAMAC_HANDLER_ERROR; + } + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetActiveRegion(LoRaMacRegion_t *region) +/* + *============================================================================= + * LORAMAC NOTIFICATIONS HANDLING + *============================================================================= + */ + +static void McpsConfirm( McpsConfirm_t *mcpsConfirm ) { - if (region == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + TxParams.IsMcpsConfirm = 1; + TxParams.Status = mcpsConfirm->Status; + TxParams.Datarate = mcpsConfirm->Datarate; + TxParams.UplinkCounter = mcpsConfirm->UpLinkCounter; + TxParams.TxPower = mcpsConfirm->TxPower; + TxParams.Channel = mcpsConfirm->Channel; + TxParams.AckReceived = mcpsConfirm->AckReceived; + + LmHandlerCallbacks->OnTxData( &TxParams ); - *region = LmHandlerParams.ActiveRegion; - return LORAMAC_HANDLER_SUCCESS; + LmHandlerPackagesNotify( PACKAGE_MCPS_CONFIRM, mcpsConfirm ); } -int32_t LmHandlerGetDevEUI(uint8_t *devEUI) +static void McpsIndication( McpsIndication_t *mcpsIndication, LoRaMacRxStatus_t *RxStatus ) { - if (devEUI == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + LmHandlerAppData_t appData; + DeviceClass_t deviceClass = CLASS_A; + RxParams.IsMcpsIndication = 1; + RxParams.Status = mcpsIndication->Status; + + if( RxParams.Status != LORAMAC_EVENT_INFO_STATUS_OK ) + { + return; + } + + RxParams.Datarate = mcpsIndication->RxDatarate; + RxParams.Rssi = RxStatus->Rssi; + RxParams.Snr = RxStatus->Snr; + RxParams.RxSlot = RxStatus->RxSlot; + RxParams.DownlinkCounter = mcpsIndication->DownLinkCounter; + + appData.Port = mcpsIndication->Port; + appData.BufferSize = mcpsIndication->BufferSize; + appData.Buffer = mcpsIndication->Buffer; - UTIL_MEM_cpy_8(devEUI, CommissioningParams.DevEui, 8); - return LORAMAC_HANDLER_SUCCESS; + LmHandlerCallbacks->OnRxData(&appData, &RxParams); + + if ((LmHandlerCallbacks->OnSysTimeUpdate != NULL) && (mcpsIndication->DeviceTimeAnsReceived == true)) + { + LmHandlerCallbacks->OnSysTimeUpdate( ); + } + + // Call packages RxProcess function + LmHandlerPackagesNotify( PACKAGE_MCPS_INDICATION, mcpsIndication ); + + LmHandlerGetCurrentClass(&deviceClass); + if ((mcpsIndication->FramePending == true) && (deviceClass == CLASS_A)) + { + // The server signals that it has pending data to be sent. + // We schedule an uplink as soon as possible to flush the server. + + // Send an empty message + LmHandlerAppData_t appData = + { + .Buffer = NULL, + .BufferSize = 0, + .Port = 0 + }; + LmHandlerSend(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); + } } -int32_t LmHandlerSetDevEUI(uint8_t *devEUI) +static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm ) { -#if ( STATIC_DEVICE_EUI != 1 ) - MibRequestConfirm_t mibReq; + TxParams.IsMcpsConfirm = 0; + TxParams.Status = mlmeConfirm->Status; + LmHandlerCallbacks->OnTxData( &TxParams ); + + LmHandlerPackagesNotify( PACKAGE_MLME_CONFIRM, mlmeConfirm ); + + switch( mlmeConfirm->MlmeRequest ) + { + case MLME_JOIN: + { + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_DEV_ADDR; + LoRaMacMibGetRequestConfirm( &mibReq ); + CommissioningParams.DevAddr = mibReq.Param.DevAddr; + LmHandlerGetTxDatarate( &JoinParams.Datarate ); + + if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) + { + // Status is OK, node has joined the network + JoinParams.Status = LORAMAC_HANDLER_SUCCESS; + LmHandlerRequestClass(LmHandlerParams.DefaultClass); + } + else + { + // Join was not successful. Try to join again + JoinParams.Status = LORAMAC_HANDLER_ERROR; + } + // Notify upper layer + LmHandlerCallbacks->OnJoinRequest( &JoinParams ); + } + break; + case MLME_LINK_CHECK: + { + RxParams.LinkCheck = true; + RxParams.DemodMargin = mlmeConfirm->DemodMargin; + RxParams.NbGateways = mlmeConfirm->NbGateways; + } + break; + case MLME_DEVICE_TIME: + { +#if ( LORAMAC_CLASSB_ENABLED == 1 ) + if( IsClassBSwitchPending == true ) + { + LmHandlerBeaconReq( ); + } +#endif /* LORAMAC_CLASSB_ENABLED == 1 */ + } + break; +#if ( LORAMAC_CLASSB_ENABLED == 1 ) + case MLME_BEACON_ACQUISITION: + { + if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) + { + // Beacon has been acquired + // Request server for ping slot + LmHandlerPingSlotReq( LmHandlerParams.PingPeriodicity ); + } + else + { + // Beacon not acquired + // Request Device Time again. + LmHandlerDeviceTimeReq( ); + } + } + break; + case MLME_PING_SLOT_INFO: + { + if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) + { + MibRequestConfirm_t mibReq; + + // Class B is now activated + mibReq.Type = MIB_DEVICE_CLASS; + mibReq.Param.Class = CLASS_B; + LoRaMacMibSetRequestConfirm( &mibReq ); + // Notify upper layer + DisplayClassUpdate( CLASS_B ); + if (LmHandlerCallbacks->OnClassChange != NULL) + { + LmHandlerCallbacks->OnClassChange( CLASS_B ); + } + IsClassBSwitchPending = false; + } + else + { + LmHandlerPingSlotReq( LmHandlerParams.PingPeriodicity ); + } + } + break; +#endif /* LORAMAC_CLASSB_ENABLED == 1 */ + default: + break; + } +} + +static void MlmeIndication( MlmeIndication_t *mlmeIndication, LoRaMacRxStatus_t *RxStatus ) +{ + RxParams.IsMcpsIndication = 0; + RxParams.Status = mlmeIndication->Status; + RxParams.Rssi = RxStatus->Rssi; + RxParams.Snr = RxStatus->Snr; + RxParams.RxSlot = RxStatus->RxSlot; + if( RxParams.Status != LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED ) + { + LmHandlerCallbacks->OnRxData( NULL, &RxParams ); + } + + switch( mlmeIndication->MlmeIndication ) + { + case MLME_SCHEDULE_UPLINK: + {// The MAC signals that we shall provide an uplink as soon as possible + // Send an empty message + LmHandlerAppData_t appData = + { + .Buffer = NULL, + .BufferSize = 0, + .Port = 0 + }; + + if( LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->IsRunning( ) == false ) + { + LmHandlerSend( &appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true ); + } + } + break; +#if ( LORAMAC_CLASSB_ENABLED == 1 ) + case MLME_BEACON_LOST: + { + MibRequestConfirm_t mibReq; + // Switch to class A again + mibReq.Type = MIB_DEVICE_CLASS; + mibReq.Param.Class = CLASS_A; + LoRaMacMibSetRequestConfirm( &mibReq ); + + BeaconParams.State = LORAMAC_HANDLER_BEACON_LOST; + BeaconParams.Info.Time.Seconds = 0; + BeaconParams.Info.GwSpecific.InfoDesc = 0; + UTIL_MEM_set_8(BeaconParams.Info.GwSpecific.Info, 0, 6); + + DisplayClassUpdate( CLASS_A ); + if (LmHandlerCallbacks->OnClassChange != NULL) + { + LmHandlerCallbacks->OnClassChange( CLASS_A ); + } + DisplayBeaconUpdate( &BeaconParams ); + + LmHandlerDeviceTimeReq( ); + } + break; + case MLME_BEACON: + { + if( mlmeIndication->Status == LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED ) + { + BeaconParams.State = LORAMAC_HANDLER_BEACON_RX; + BeaconParams.Info = mlmeIndication->BeaconInfo; + + DisplayBeaconUpdate( &BeaconParams ); + } + else + { + BeaconParams.State = LORAMAC_HANDLER_BEACON_NRX; + BeaconParams.Info = mlmeIndication->BeaconInfo; + + DisplayBeaconUpdate( &BeaconParams ); + } + } + break; +#endif /* LORAMAC_CLASSB_ENABLED == 1 */ + default: + break; + } +} + +/* + *============================================================================= + * PACKAGES HANDLING + *============================================================================= + */ + +LmHandlerErrorStatus_t LmHandlerPackageRegister( uint8_t id, void *params ) +{ + LmhPackage_t *package = NULL; + switch( id ) + { + case PACKAGE_ID_COMPLIANCE: + { + package = LmhpCompliancePackageFactory( ); + break; + } + default: + { +#if (!defined (LORAWAN_DATA_DISTRIB_MGT) || (LORAWAN_DATA_DISTRIB_MGT == 0)) +#else /*LORAWAN_DATA_DISTRIB_MGT == 1*/ + LmhpPackagesRegister(id, &package); +#endif /*LORAWAN_DATA_DISTRIB_MGT*/ + break; + } + } + if( package != NULL ) + { + LmHandlerPackages[id] = package; + LmHandlerPackages[id]->OnJoinRequest = LmHandlerJoin; + LmHandlerPackages[id]->OnSendRequest = LmHandlerSend; + LmHandlerPackages[id]->OnDeviceTimeRequest = LmHandlerDeviceTimeReq; + LmHandlerPackages[id]->OnPackageProcessEvent = LmHandlerCallbacks->OnMacProcess; + LmHandlerPackages[id]->Init( params, AppData.Buffer, AppData.BufferSize ); + + return LORAMAC_HANDLER_SUCCESS; + } + else + { + return LORAMAC_HANDLER_ERROR; + } +} + +static bool LmHandlerPackageIsInitialized( uint8_t id ) +{ + if (( id < PKG_MAX_NUMBER ) && ( LmHandlerPackages[id]->IsInitialized != NULL )) + { + return LmHandlerPackages[id]->IsInitialized( ); + } + else + { + return false; + } +} + +static void LmHandlerPackagesNotify( PackageNotifyTypes_t notifyType, void *params ) +{ + for( int8_t i = 0; i < PKG_MAX_NUMBER; i++ ) + { + if( LmHandlerPackages[i] != NULL ) + { + switch( notifyType ) + { + case PACKAGE_MCPS_CONFIRM: + { + if( LmHandlerPackages[i]->OnMcpsConfirmProcess != NULL ) + { + LmHandlerPackages[i]->OnMcpsConfirmProcess( ( McpsConfirm_t* ) params ); + } + break; + } + case PACKAGE_MCPS_INDICATION: + { + if( ( LmHandlerPackages[i]->OnMcpsIndicationProcess != NULL ) && + ( ( LmHandlerPackages[i]->Port == ((McpsIndication_t* )params)->Port ) || + ( ( i == PACKAGE_ID_COMPLIANCE ) && ( LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->IsRunning() )))) + { + LmHandlerPackages[i]->OnMcpsIndicationProcess( ( McpsIndication_t* )params ); + } + break; + } + case PACKAGE_MLME_CONFIRM: + { + if( LmHandlerPackages[i]->OnMlmeConfirmProcess != NULL ) + { + LmHandlerPackages[i]->OnMlmeConfirmProcess( ( MlmeConfirm_t* )params ); + } + break; + } + default: + { + break; + } + } + } + } +} + +static void LmHandlerPackagesProcess( void ) +{ + for( int8_t i = 0; i < PKG_MAX_NUMBER; i++ ) + { + if( ( LmHandlerPackages[i] != NULL ) && + ( LmHandlerPackages[i]->Process != NULL ) && + ( LmHandlerPackageIsInitialized( i ) != false ) ) + { + LmHandlerPackages[i]->Process( ); + } + } +} + +LmHandlerErrorStatus_t LmHandlerGetDevEUI(uint8_t *devEUI) +{ + MibRequestConfirm_t mibReq; + if (devEUI == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - /* Not yet joined */ - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { mibReq.Type = MIB_DEV_EUI; - UTIL_MEM_cpy_8(mibReq.Param.DevEui, devEUI, SE_EUI_SIZE); - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) { - return LORAMAC_HANDLER_ERROR; + return LORAMAC_HANDLER_ERROR; } - UTIL_MEM_cpy_8(CommissioningParams.DevEui, devEUI, SE_EUI_SIZE); + UTIL_MEM_cpy_8(devEUI, mibReq.Param.DevEui, SE_EUI_SIZE); return LORAMAC_HANDLER_SUCCESS; - } - else - { - /* Cannot change Keys in running state */ - return LORAMAC_HANDLER_ERROR; - } +} + +LmHandlerErrorStatus_t LmHandlerSetDevEUI(uint8_t *devEUI) +{ +#if ( STATIC_DEVICE_EUI != 1 ) + MibRequestConfirm_t mibReq; + + /* Not yet joined */ + if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) + { + mibReq.Type = MIB_DEV_EUI; + mibReq.Param.DevEui = devEUI; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change Keys in running state */ + return LORAMAC_HANDLER_ERROR; + } #else /* STATIC_DEVICE_EUI == 1 */ - return LORAMAC_HANDLER_ERROR; + return LORAMAC_HANDLER_ERROR; #endif /* STATIC_DEVICE_EUI */ } -int32_t LmHandlerGetAppEUI(uint8_t *appEUI) +LmHandlerErrorStatus_t LmHandlerGetAppEUI(uint8_t *appEUI) { - if (appEUI == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; - UTIL_MEM_cpy_8(appEUI, CommissioningParams.JoinEui, 8); + if (appEUI == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - return LORAMAC_HANDLER_SUCCESS; + mibReq.Type = MIB_JOIN_EUI; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + UTIL_MEM_cpy_8(appEUI, mibReq.Param.JoinEui, SE_EUI_SIZE); + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetAppEUI(uint8_t *appEUI) +LmHandlerErrorStatus_t LmHandlerSetAppEUI(uint8_t *appEUI) { - /* Not yet joined */ - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - UTIL_MEM_cpy_8(CommissioningParams.JoinEui, appEUI, 8); - return LmHandlerConfigure(&LmHandlerParams); - } - else - { - /* Cannot change Keys in running state */ - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + + /* Not yet joined */ + if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) + { + mibReq.Type = MIB_JOIN_EUI; + mibReq.Param.JoinEui = appEUI; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change Keys in running state */ + return LORAMAC_HANDLER_ERROR; + } } -int32_t LmHandlerGetNetworkID(uint32_t *networkId) +LmHandlerErrorStatus_t LmHandlerGetNetworkID(uint32_t *networkId) { - if (networkId == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + + if (networkId == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - *networkId = CommissioningParams.NetworkId; - return LORAMAC_HANDLER_SUCCESS; + mibReq.Type = MIB_NET_ID; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + *networkId = mibReq.Param.NetID; + return LORAMAC_HANDLER_SUCCESS; +} + +LmHandlerErrorStatus_t LmHandlerSetNetworkID(uint32_t networkId) +{ + MibRequestConfirm_t mibReq; + + /* Not yet joined */ + if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) + { + mibReq.Type = MIB_NET_ID; + mibReq.Param.NetID = networkId; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change NetworkID in running state */ + return LORAMAC_HANDLER_ERROR; + } } -int32_t LmHandlerSetNetworkID(uint32_t networkId) +LmHandlerErrorStatus_t LmHandlerGetDevAddr(uint32_t *devAddr) { - /* Not yet joined */ - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - CommissioningParams.NetworkId = networkId; - return LmHandlerConfigure(&LmHandlerParams); - } - else - { - /* Cannot change NetworkID in running state */ - return LORAMAC_HANDLER_ERROR; - } -} + MibRequestConfirm_t mibReq; -int32_t LmHandlerGetDevAddr(uint32_t *devAddr) -{ - if (devAddr == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + if (devAddr == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - *devAddr = CommissioningParams.DevAddr; - return LORAMAC_HANDLER_SUCCESS; + mibReq.Type = MIB_DEV_ADDR; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + *devAddr = mibReq.Param.DevAddr; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetDevAddr(uint32_t devAddr) +LmHandlerErrorStatus_t LmHandlerSetDevAddr(uint32_t devAddr) { #if ( STATIC_DEVICE_ADDRESS != 1 ) - /* Not yet joined */ - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - CommissioningParams.DevAddr = devAddr; - return LmHandlerConfigure(&LmHandlerParams); - } - else - { - /* Cannot change DevAddr in running state */ - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + + /* Not yet joined */ + if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) + { + mibReq.Type = MIB_DEV_ADDR; + mibReq.Param.DevAddr = devAddr; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change DevAddr in running state */ + return LORAMAC_HANDLER_ERROR; + } #else /* STATIC_DEVICE_ADDRESS == 1 */ - return LORAMAC_HANDLER_ERROR; + return LORAMAC_HANDLER_ERROR; #endif /* STATIC_DEVICE_ADDRESS */ } -int32_t LmHandlerSetActiveRegion(LoRaMacRegion_t region) +LmHandlerErrorStatus_t LmHandlerSetActiveRegion(LoRaMacRegion_t region) { - /* Not yet joined */ - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - LmHandlerParams.ActiveRegion = region; - return LmHandlerConfigure(&LmHandlerParams); - } - else - { - /* Cannot change Region in running state */ - return LORAMAC_HANDLER_ERROR; - } + /* Not yet joined */ + if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) + { + LmHandlerParams.ActiveRegion = region; + return LmHandlerConfigure( &LmHandlerParams ); + } + else + { + /* Cannot change Region in running state */ + return LORAMAC_HANDLER_ERROR; + } } -int32_t LmHandlerGetAdrEnable(bool *adrEnable) +LmHandlerErrorStatus_t LmHandlerGetAdrEnable(bool *adrEnable) { - if (adrEnable == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + if (adrEnable == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - *adrEnable = LmHandlerParams.AdrEnable; - return LORAMAC_HANDLER_SUCCESS; + *adrEnable = LmHandlerParams.AdrEnable; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetAdrEnable(bool adrEnable) +LmHandlerErrorStatus_t LmHandlerSetAdrEnable(bool adrEnable) { - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_ADR; - mibReq.Param.AdrEnable = adrEnable; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } - LmHandlerParams.AdrEnable = adrEnable; + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_ADR; + mibReq.Param.AdrEnable = adrEnable; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + LmHandlerParams.AdrEnable = adrEnable; - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetTxDatarate(int8_t txDatarate) +LmHandlerErrorStatus_t LmHandlerSetTxDatarate(int8_t txDatarate) { - if (LmHandlerParams.AdrEnable == true) - { - return LORAMAC_HANDLER_ERROR; - } + if (LmHandlerParams.AdrEnable == true) + { + return LORAMAC_HANDLER_ERROR; + } - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_CHANNELS_DATARATE; - mibReq.Param.ChannelsDatarate = txDatarate; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_CHANNELS_DATARATE; + mibReq.Param.ChannelsDatarate = txDatarate; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - LmHandlerParams.TxDatarate = txDatarate; + LmHandlerParams.TxDatarate = txDatarate; - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetDutyCycleEnable(bool *dutyCycleEnable) +LmHandlerErrorStatus_t LmHandlerGetDutyCycleEnable(bool *dutyCycleEnable) { - if (dutyCycleEnable == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + if (dutyCycleEnable == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - *dutyCycleEnable = LmHandlerParams.DutyCycleEnabled; - return LORAMAC_HANDLER_SUCCESS; + *dutyCycleEnable = LmHandlerParams.DutyCycleEnabled; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetDutyCycleEnable(bool dutyCycleEnable) +LmHandlerErrorStatus_t LmHandlerSetDutyCycleEnable(bool dutyCycleEnable) { - LmHandlerParams.DutyCycleEnabled = dutyCycleEnable; - LoRaMacTestSetDutyCycleOn(dutyCycleEnable); + LmHandlerParams.DutyCycleEnabled = dutyCycleEnable; + LoRaMacTestSetDutyCycleOn(dutyCycleEnable); - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetRX2Params(RxChannelParams_t *rxParams) +LmHandlerErrorStatus_t LmHandlerGetRX2Params(RxChannelParams_t *rxParams) { - if (rxParams == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + if (rxParams == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - MibRequestConfirm_t mibReq; + MibRequestConfirm_t mibReq; - mibReq.Type = MIB_RX2_CHANNEL; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_RX2_CHANNEL; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - rxParams->Frequency = mibReq.Param.Rx2Channel.Frequency; - rxParams->Datarate = mibReq.Param.Rx2Channel.Datarate; - return LORAMAC_HANDLER_SUCCESS; + rxParams->Frequency = mibReq.Param.Rx2Channel.Frequency; + rxParams->Datarate = mibReq.Param.Rx2Channel.Datarate; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetTxPower(int8_t *txPower) +LmHandlerErrorStatus_t LmHandlerGetTxPower(int8_t *txPower) { - MibRequestConfirm_t mibReq; - if (txPower == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + if (txPower == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - mibReq.Type = MIB_CHANNELS_TX_POWER; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_CHANNELS_TX_POWER; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - *txPower = mibReq.Param.ChannelsTxPower; - return LORAMAC_HANDLER_SUCCESS; + *txPower = mibReq.Param.ChannelsTxPower; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetRx1Delay(uint32_t *rxDelay) +LmHandlerErrorStatus_t LmHandlerGetRx1Delay(uint32_t *rxDelay) { - MibRequestConfirm_t mibReq; - if (rxDelay == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + if (rxDelay == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - mibReq.Type = MIB_RECEIVE_DELAY_1; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_RECEIVE_DELAY_1; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - *rxDelay = mibReq.Param.ReceiveDelay1; - return LORAMAC_HANDLER_SUCCESS; + *rxDelay = mibReq.Param.ReceiveDelay1; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetRx2Delay(uint32_t *rxDelay) +LmHandlerErrorStatus_t LmHandlerGetRx2Delay(uint32_t *rxDelay) { - MibRequestConfirm_t mibReq; - if (rxDelay == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + if (rxDelay == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - mibReq.Type = MIB_RECEIVE_DELAY_2; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_RECEIVE_DELAY_2; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - *rxDelay = mibReq.Param.ReceiveDelay2; - return LORAMAC_HANDLER_SUCCESS; + *rxDelay = mibReq.Param.ReceiveDelay2; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetJoinRx1Delay(uint32_t *rxDelay) +LmHandlerErrorStatus_t LmHandlerGetJoinRx1Delay(uint32_t *rxDelay) { - MibRequestConfirm_t mibReq; - if (rxDelay == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + if (rxDelay == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - mibReq.Type = MIB_JOIN_ACCEPT_DELAY_1; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_JOIN_ACCEPT_DELAY_1; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - *rxDelay = mibReq.Param.JoinAcceptDelay1; - return LORAMAC_HANDLER_SUCCESS; + *rxDelay = mibReq.Param.JoinAcceptDelay1; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetJoinRx2Delay(uint32_t *rxDelay) +LmHandlerErrorStatus_t LmHandlerGetJoinRx2Delay(uint32_t *rxDelay) { - MibRequestConfirm_t mibReq; - if (rxDelay == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + if (rxDelay == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - mibReq.Type = MIB_JOIN_ACCEPT_DELAY_2; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_JOIN_ACCEPT_DELAY_2; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - *rxDelay = mibReq.Param.JoinAcceptDelay2; - return LORAMAC_HANDLER_SUCCESS; + *rxDelay = mibReq.Param.JoinAcceptDelay2; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetTxPower(int8_t txPower) +LmHandlerErrorStatus_t LmHandlerSetTxPower(int8_t txPower) { - MibRequestConfirm_t mibReq; + MibRequestConfirm_t mibReq; - mibReq.Type = MIB_CHANNELS_TX_POWER; - mibReq.Param.ChannelsTxPower = txPower; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_CHANNELS_TX_POWER; + mibReq.Param.ChannelsTxPower = txPower; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetRX2Params(RxChannelParams_t *rxParams) +LmHandlerErrorStatus_t LmHandlerSetRX2Params(RxChannelParams_t *rxParams) { - MibRequestConfirm_t mibReq; + MibRequestConfirm_t mibReq; - mibReq.Type = MIB_RX2_CHANNEL; - mibReq.Param.Rx2Channel.Frequency = rxParams->Frequency; - mibReq.Param.Rx2Channel.Datarate = rxParams->Datarate; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + mibReq.Type = MIB_RX2_CHANNEL; + mibReq.Param.Rx2Channel.Frequency = rxParams->Frequency; + mibReq.Param.Rx2Channel.Datarate = rxParams->Datarate; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetRx1Delay(uint32_t rxDelay) +LmHandlerErrorStatus_t LmHandlerSetRx1Delay(uint32_t rxDelay) { - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_RECEIVE_DELAY_1; - mibReq.Param.ReceiveDelay1 = rxDelay; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_RECEIVE_DELAY_1; + mibReq.Param.ReceiveDelay1 = rxDelay; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetRx2Delay(uint32_t rxDelay) +LmHandlerErrorStatus_t LmHandlerSetRx2Delay(uint32_t rxDelay) { - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_RECEIVE_DELAY_2; - mibReq.Param.ReceiveDelay2 = rxDelay; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_RECEIVE_DELAY_2; + mibReq.Param.ReceiveDelay2 = rxDelay; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetJoinRx1Delay(uint32_t rxDelay) +LmHandlerErrorStatus_t LmHandlerSetJoinRx1Delay(uint32_t rxDelay) { - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_JOIN_ACCEPT_DELAY_1; - mibReq.Param.JoinAcceptDelay1 = rxDelay; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_JOIN_ACCEPT_DELAY_1; + mibReq.Param.JoinAcceptDelay1 = rxDelay; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerSetJoinRx2Delay(uint32_t rxDelay) +LmHandlerErrorStatus_t LmHandlerSetJoinRx2Delay(uint32_t rxDelay) { - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_JOIN_ACCEPT_DELAY_2; - mibReq.Param.JoinAcceptDelay2 = rxDelay; - if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_JOIN_ACCEPT_DELAY_2; + mibReq.Param.JoinAcceptDelay2 = rxDelay; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - return LORAMAC_HANDLER_SUCCESS; + return LORAMAC_HANDLER_SUCCESS; } -int32_t LmHandlerGetPingPeriodicity(uint8_t *pingPeriodicity) +LmHandlerErrorStatus_t LmHandlerGetPingPeriodicity(uint8_t *pingPeriodicity) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) - if (pingPeriodicity == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + if (pingPeriodicity == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - *pingPeriodicity = LmHandlerParams.PingPeriodicity; - return LORAMAC_HANDLER_SUCCESS; + *pingPeriodicity = LmHandlerParams.PingPeriodicity; + return LORAMAC_HANDLER_SUCCESS; #else /* LORAMAC_CLASSB_ENABLED == 0 */ - return LORAMAC_HANDLER_ERROR; + return LORAMAC_HANDLER_ERROR; #endif /* LORAMAC_CLASSB_ENABLED */ } -int32_t LmHandlerSetPingPeriodicity(uint8_t pingPeriodicity) +LmHandlerErrorStatus_t LmHandlerSetPingPeriodicity(uint8_t pingPeriodicity) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) - /* Not yet joined */ - if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) - { - LmHandlerParams.PingPeriodicity = pingPeriodicity; - return LORAMAC_HANDLER_SUCCESS; - } - else - { - /* Cannot change Region in running state */ - return LmHandlerPingSlotReq(pingPeriodicity); - } + /* Not yet joined */ + if (LmHandlerJoinStatus() != LORAMAC_HANDLER_SET) + { + LmHandlerParams.PingPeriodicity = pingPeriodicity; + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change Region in running state */ + return LmHandlerPingSlotReq(pingPeriodicity); + } #else /* LORAMAC_CLASSB_ENABLED == 0 */ - return LORAMAC_HANDLER_ERROR; + return LORAMAC_HANDLER_ERROR; #endif /* LORAMAC_CLASSB_ENABLED */ } -int32_t LmHandlerGetBeaconState(BeaconState_t *beaconState) +LmHandlerErrorStatus_t LmHandlerGetBeaconState(BeaconState_t *beaconState) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) - MibRequestConfirm_t mibReq; - LoRaMacClassBNvmCtx_t *CtxClassB; + MibRequestConfirm_t mibReq; - if (beaconState == NULL) - { - return LORAMAC_HANDLER_ERROR; - } - - mibReq.Type = MIB_NVM_CTXS; - if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_ERROR; - } - CtxClassB = (LoRaMacClassBNvmCtx_t *) mibReq.Param.Contexts->ClassBNvmCtx; - if (CtxClassB == NULL) - { - return LORAMAC_HANDLER_ERROR; - } + if (beaconState == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - *beaconState = CtxClassB->BeaconCtx.BeaconState; - return LORAMAC_HANDLER_SUCCESS; + mibReq.Type = MIB_BEACON_STATE; + if (LoRaMacMibGetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + *beaconState = mibReq.Param.BeaconState; + return LORAMAC_HANDLER_SUCCESS; #else /* LORAMAC_CLASSB_ENABLED == 0 */ - return LORAMAC_HANDLER_ERROR; + return LORAMAC_HANDLER_ERROR; #endif /* LORAMAC_CLASSB_ENABLED */ } -/* Private functions ---------------------------------------------------------*/ -static LmHandlerErrorStatus_t LmHandlerDeviceTimeReq(void) +LmHandlerErrorStatus_t LmHandlerGetNwkKey( uint8_t *nwkKey ) { - LoRaMacStatus_t status; - MlmeReq_t mlmeReq; - - mlmeReq.Type = MLME_DEVICE_TIME; - - status = LoRaMacMlmeRequest(&mlmeReq); + Key_t *keyItem; + if (nwkKey == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - if (status == LORAMAC_STATUS_OK) - { + if (SECURE_ELEMENT_SUCCESS != SecureElementGetKeyByID(NWK_KEY, &keyItem)) + { + return LORAMAC_HANDLER_ERROR; + } + UTIL_MEM_cpy_8( nwkKey, keyItem->KeyValue, 16 ); return LORAMAC_HANDLER_SUCCESS; - } - else - { - return LORAMAC_HANDLER_ERROR; - } } -#if ( LORAMAC_CLASSB_ENABLED == 1 ) -static LmHandlerErrorStatus_t LmHandlerBeaconReq(void) +LmHandlerErrorStatus_t LmHandlerSetNwkKey( uint8_t *nwkKey ) { - LoRaMacStatus_t status = LORAMAC_STATUS_OK; - MlmeReq_t mlmeReq; - - mlmeReq.Type = MLME_BEACON_ACQUISITION; - - status = LoRaMacMlmeRequest(&mlmeReq); - - if (status == LORAMAC_STATUS_OK) - { - return LORAMAC_HANDLER_SUCCESS; - } - else - { - return LORAMAC_HANDLER_ERROR; - } + /* Not yet joined */ + if( LmHandlerJoinStatus( ) != LORAMAC_HANDLER_SET ) + { + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NWK_KEY; + mibReq.Param.NwkKey = nwkKey; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change Keys in running state */ + return LORAMAC_HANDLER_ERROR; + } } -static LmHandlerErrorStatus_t LmHandlerPingSlotReq(uint8_t periodicity) +LmHandlerErrorStatus_t LmHandlerGetAppKey( uint8_t *appKey ) { - LoRaMacStatus_t status; - MlmeReq_t mlmeReq; - - mlmeReq.Type = MLME_PING_SLOT_INFO; - mlmeReq.Req.PingSlotInfo.PingSlot.Fields.Periodicity = periodicity; - mlmeReq.Req.PingSlotInfo.PingSlot.Fields.RFU = 0; - - status = LoRaMacMlmeRequest(&mlmeReq); + Key_t *keyItem; + if (appKey == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - if (status == LORAMAC_STATUS_OK) - { - LmHandlerParams.PingPeriodicity = periodicity; - /* Send an empty message */ - LmHandlerAppData_t appData = + if (SECURE_ELEMENT_SUCCESS != SecureElementGetKeyByID(APP_KEY, &keyItem)) { - .Buffer = NULL, - .BufferSize = 0, - .Port = 0 - }; - return LmHandlerSend(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, false); - } - else - { - return LORAMAC_HANDLER_ERROR; - } + return LORAMAC_HANDLER_ERROR; + } + UTIL_MEM_cpy_8( appKey, keyItem->KeyValue, 16 ); + return LORAMAC_HANDLER_SUCCESS; } -#endif /* LORAMAC_CLASSB_ENABLED == 1 */ -static void McpsConfirm(McpsConfirm_t *mcpsConfirm) +LmHandlerErrorStatus_t LmHandlerSetAppKey( uint8_t *appKey ) { - TxParams.IsMcpsConfirm = 1; - TxParams.Status = mcpsConfirm->Status; - TxParams.Datarate = mcpsConfirm->Datarate; - TxParams.UplinkCounter = mcpsConfirm->UpLinkCounter; - TxParams.TxPower = mcpsConfirm->TxPower; - TxParams.Channel = mcpsConfirm->Channel; - TxParams.AckReceived = mcpsConfirm->AckReceived; - - LmHandlerCallbacks.OnTxData(&TxParams); - - LmHandlerPackagesNotify(PACKAGE_MCPS_CONFIRM, mcpsConfirm); + /* Not yet joined */ + if( LmHandlerJoinStatus( ) != LORAMAC_HANDLER_SET ) + { + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_APP_KEY; + mibReq.Param.AppKey = appKey; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change Keys in running state */ + return LORAMAC_HANDLER_ERROR; + } } -static void McpsIndication(McpsIndication_t *mcpsIndication) +LmHandlerErrorStatus_t LmHandlerGetNwkSKey( uint8_t *nwkSKey ) { - LmHandlerAppData_t appData; - DeviceClass_t deviceClass; - RxParams.IsMcpsIndication = 1; - RxParams.Status = mcpsIndication->Status; - - if (RxParams.Status != LORAMAC_EVENT_INFO_STATUS_OK) - { - return; - } - - if (mcpsIndication->BufferSize > 0) - { - RxParams.Datarate = mcpsIndication->RxDatarate; - RxParams.Rssi = mcpsIndication->Rssi; - RxParams.Snr = mcpsIndication->Snr; - RxParams.DownlinkCounter = mcpsIndication->DownLinkCounter; - RxParams.RxSlot = mcpsIndication->RxSlot; - - appData.Port = mcpsIndication->Port; - appData.BufferSize = mcpsIndication->BufferSize; - appData.Buffer = mcpsIndication->Buffer; - - LmHandlerCallbacks.OnRxData(&appData, &RxParams); - } - - /* Call packages RxProcess function */ - LmHandlerPackagesNotify(PACKAGE_MCPS_INDICATION, mcpsIndication); - LmHandlerGetCurrentClass(&deviceClass); - if ((mcpsIndication->FramePending == true) && (deviceClass == CLASS_A)) - { - /* The server signals that it has pending data to be sent. */ - /* We schedule an uplink as soon as possible to flush the server. */ + Key_t *keyItem; + if (nwkSKey == NULL) + { + return LORAMAC_HANDLER_ERROR; + } - /* Send an empty message */ - LmHandlerAppData_t appData = + if (SECURE_ELEMENT_SUCCESS != SecureElementGetKeyByID(NWK_S_KEY, &keyItem)) { - .Buffer = NULL, - .BufferSize = 0, - .Port = 0 - }; - LmHandlerSend(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); - } + return LORAMAC_HANDLER_ERROR; + } + UTIL_MEM_cpy_8( nwkSKey, keyItem->KeyValue, 16 ); + return LORAMAC_HANDLER_SUCCESS; } -static void MlmeConfirm(MlmeConfirm_t *mlmeConfirm) +LmHandlerErrorStatus_t LmHandlerSetNwkSKey( uint8_t *nwkSKey ) { - TxParams.IsMcpsConfirm = 0; - TxParams.Status = mlmeConfirm->Status; - - LmHandlerPackagesNotify(PACKAGE_MLME_CONFIRM, mlmeConfirm); - - switch (mlmeConfirm->MlmeRequest) - { - case MLME_JOIN: + /* Not yet joined */ + if( LmHandlerJoinStatus( ) != LORAMAC_HANDLER_SET ) { - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_DEV_ADDR; - LoRaMacMibGetRequestConfirm(&mibReq); - CommissioningParams.DevAddr = mibReq.Param.DevAddr; - LmHandlerGetTxDatarate(&JoinParams.Datarate); - - if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) - { - /* Status is OK, node has joined the network */ - JoinParams.Status = LORAMAC_HANDLER_SUCCESS; + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NWK_S_KEY; + mibReq.Param.NwkSKey = nwkSKey; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) + { + return LORAMAC_HANDLER_ERROR; + } - /* Notify upper layer */ - LmHandlerRequestClass(LmHandlerParams.DefaultClass); - } - else - { - /* Join was not successful. Try to join again */ - JoinParams.Status = LORAMAC_HANDLER_ERROR; - } - LmHandlerCallbacks.OnJoinRequest(&JoinParams); - } - break; - case MLME_LINK_CHECK: - { - /* Check DemodMargin */ - /* Check NbGateways */ - } - break; - case MLME_DEVICE_TIME: - { -#if ( LORAMAC_CLASSB_ENABLED == 1 ) - if (IsClassBSwitchPending == true) - { - LmHandlerBeaconReq(); - } -#endif /* LORAMAC_CLASSB_ENABLED == 1 */ + return LORAMAC_HANDLER_SUCCESS; } - break; -#if ( LORAMAC_CLASSB_ENABLED == 1 ) - case MLME_BEACON_ACQUISITION: - { - if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) - { - /* Beacon has been acquired */ - /* Request server for ping slot */ - LmHandlerPingSlotReq(LmHandlerParams.PingPeriodicity); - } - else - { - /* Beacon not acquired */ - /* Request Device Time again. */ - LmHandlerDeviceTimeReq(); - } - } - break; - case MLME_PING_SLOT_INFO: + else { - if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) - { - MibRequestConfirm_t mibReq; - - /* Class B is now activated */ - mibReq.Type = MIB_DEVICE_CLASS; - mibReq.Param.Class = CLASS_B; - LoRaMacMibSetRequestConfirm(&mibReq); - - DisplayClassUpdate(CLASS_B); - - IsClassBSwitchPending = false; - } - else - { - LmHandlerPingSlotReq(LmHandlerParams.PingPeriodicity); - } + /* Cannot change Keys in running state */ + return LORAMAC_HANDLER_ERROR; } - break; -#endif /* LORAMAC_CLASSB_ENABLED == 1 */ - default: - break; - } } -static void MlmeIndication(MlmeIndication_t *mlmeIndication) +LmHandlerErrorStatus_t LmHandlerGetAppSKey( uint8_t *appSKey ) { - RxParams.IsMcpsIndication = 0; - RxParams.Status = mlmeIndication->Status; - - switch (mlmeIndication->MlmeIndication) - { -#if ( LORAMAC_CLASSB_ENABLED == 1 ) - case MLME_BEACON_LOST: + Key_t *keyItem; + if (appSKey == NULL) { - MibRequestConfirm_t mibReq; - /* Switch to class A again */ - mibReq.Type = MIB_DEVICE_CLASS; - mibReq.Param.Class = CLASS_A; - LoRaMacMibSetRequestConfirm(&mibReq); - - BeaconParams.State = LORAMAC_HANDLER_BEACON_LOST; - BeaconParams.Info.Time.Seconds = 0; - BeaconParams.Info.GwSpecific.InfoDesc = 0; - UTIL_MEM_set_8(BeaconParams.Info.GwSpecific.Info, 0, 6); - - DisplayClassUpdate(CLASS_A); - DisplayBeaconUpdate(&BeaconParams); - - LmHandlerDeviceTimeReq(); + return LORAMAC_HANDLER_ERROR; } - break; - case MLME_BEACON: - { - if (mlmeIndication->Status == LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED) - { - BeaconParams.State = LORAMAC_HANDLER_BEACON_RX; - BeaconParams.Info = mlmeIndication->BeaconInfo; - DisplayBeaconUpdate(&BeaconParams); - } - else - { - BeaconParams.State = LORAMAC_HANDLER_BEACON_NRX; - BeaconParams.Info = mlmeIndication->BeaconInfo; - - DisplayBeaconUpdate(&BeaconParams); - } - break; + if (SECURE_ELEMENT_SUCCESS != SecureElementGetKeyByID(APP_S_KEY, &keyItem)) + { + return LORAMAC_HANDLER_ERROR; } -#endif /* LORAMAC_CLASSB_ENABLED == 1 */ - default: - break; - } -} - -static bool LmHandlerPackageIsInitialized(uint8_t id) -{ - if ((id < PKG_MAX_NUMBER) && (LmHandlerPackages[id]->IsInitialized != NULL)) - { - return LmHandlerPackages[id]->IsInitialized(); - } - else - { - return false; - } + UTIL_MEM_cpy_8( appSKey, keyItem->KeyValue, 16 ); + return LORAMAC_HANDLER_SUCCESS; } -static void LmHandlerPackagesNotify(PackageNotifyTypes_t notifyType, void *params) +LmHandlerErrorStatus_t LmHandlerSetAppSKey( uint8_t *appSKey ) { - for (int8_t i = 0; i < PKG_MAX_NUMBER; i++) - { - if (LmHandlerPackages[i] != NULL) + /* Not yet joined */ + if( LmHandlerJoinStatus( ) != LORAMAC_HANDLER_SET ) { - switch (notifyType) - { - case PACKAGE_MCPS_CONFIRM: - { - if (LmHandlerPackages[i]->OnMcpsConfirmProcess != NULL) - { - LmHandlerPackages[i]->OnMcpsConfirmProcess(params); - } - break; - } - case PACKAGE_MCPS_INDICATION: - { - if ((LmHandlerPackages[i]->OnMcpsIndicationProcess != NULL) && - ((LmHandlerPackages[i]->Port == ((McpsIndication_t *)params)->Port) || - ((i == PACKAGE_ID_COMPLIANCE) && (LmHandlerPackages[PACKAGE_ID_COMPLIANCE]->IsRunning())))) - { - LmHandlerPackages[i]->OnMcpsIndicationProcess(params); - } - break; - } - case PACKAGE_MLME_CONFIRM: + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_APP_S_KEY; + mibReq.Param.AppSKey = appSKey; + if (LoRaMacMibSetRequestConfirm(&mibReq) != LORAMAC_STATUS_OK) { - if (LmHandlerPackages[i]->OnMlmeConfirmProcess != NULL) - { - LmHandlerPackages[i]->OnMlmeConfirmProcess(params); - } - break; + return LORAMAC_HANDLER_ERROR; } - default: - break; - } + + return LORAMAC_HANDLER_SUCCESS; + } + else + { + /* Cannot change Keys in running state */ + return LORAMAC_HANDLER_ERROR; } - } } static void DisplayClassUpdate(DeviceClass_t deviceClass) { - MW_LOG(TS_OFF, VLEVEL_M, "Switch to Class %c done\r\n", "ABC"[deviceClass]); + MW_LOG(TS_OFF, VLEVEL_M, "Switch to Class %c done\r\n", "ABC"[deviceClass]); } #if ( LORAMAC_CLASSB_ENABLED == 1 ) static void DisplayBeaconUpdate(LmHandlerBeaconParams_t *params) { - static const char *EventBeaconStateStrings[] = { "BC_ACQUIRING", "BC_LOST", "BC_RECEIVED", "BC_NOT_RECEIVED" }; - - MW_LOG(TS_OFF, VLEVEL_M, "\r\n###### ========== %s\r\n", EventBeaconStateStrings[params->State]); - if (params->State == LORAMAC_HANDLER_BEACON_RX) - { - MW_LOG(TS_OFF, VLEVEL_H, "###### BTIME:%010d | GW DESC:%d | GW INFO:%02X %02X %02X %02X %02X %02X\r\n", - params->Info.Time.Seconds, params->Info.GwSpecific.InfoDesc, - params->Info.GwSpecific.Info[0], params->Info.GwSpecific.Info[1], - params->Info.GwSpecific.Info[2], params->Info.GwSpecific.Info[3], - params->Info.GwSpecific.Info[4], params->Info.GwSpecific.Info[5]); - MW_LOG(TS_OFF, VLEVEL_H, "###### FREQ:%d | DR:%d | RSSI:%d | SNR:%d\r\n", - params->Info.Frequency, params->Info.Datarate, - params->Info.Rssi, params->Info.Snr); - } + static const char *EventBeaconStateStrings[] = { "BC_ACQUIRING", "BC_LOST", "BC_RECEIVED", "BC_NOT_RECEIVED" }; + + MW_LOG(TS_OFF, VLEVEL_M, "\r\n###### ========== %s\r\n", EventBeaconStateStrings[params->State]); + if (params->State == LORAMAC_HANDLER_BEACON_RX) + { + MW_LOG(TS_OFF, VLEVEL_H, "###### BTIME:%010d | GW DESC:%d | GW INFO:%02X %02X %02X %02X %02X %02X\r\n", + params->Info.Time.Seconds, params->Info.GwSpecific.InfoDesc, + params->Info.GwSpecific.Info[0], params->Info.GwSpecific.Info[1], + params->Info.GwSpecific.Info[2], params->Info.GwSpecific.Info[3], + params->Info.GwSpecific.Info[4], params->Info.GwSpecific.Info[5]); + MW_LOG(TS_OFF, VLEVEL_H, "###### FREQ:%d | DR:%d | RSSI:%d | SNR:%d\r\n", + params->Info.Frequency, params->Info.Datarate, + params->Info.Rssi, params->Info.Snr); + } } #endif /* LORAMAC_CLASSB_ENABLED == 1 */ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.h index af796110..ee17e6a1 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandler.h @@ -36,7 +36,8 @@ #define __LORAMAC_HANDLER_H__ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Includes ------------------------------------------------------------------*/ @@ -49,11 +50,11 @@ extern "C" { /*! * \brief Join notification parameters */ - typedef struct LmHandlerJoinParams_s +typedef struct LmHandlerJoinParams_s { - int8_t Datarate; - LmHandlerErrorStatus_t Status; - ActivationType_t Mode; + int8_t Datarate; + LmHandlerErrorStatus_t Status; + ActivationType_t Mode; } LmHandlerJoinParams_t; /*! @@ -61,159 +62,218 @@ extern "C" { */ typedef struct LmHandlerTxParams_s { - uint8_t IsMcpsConfirm; - LoRaMacEventInfoStatus_t Status; - LmHandlerMsgTypes_t MsgType; - uint8_t AckReceived; - int8_t Datarate; - uint32_t UplinkCounter; - LmHandlerAppData_t AppData; - int8_t TxPower; - uint8_t Channel; -} LmHandlerTxParams_t; + uint8_t IsMcpsConfirm; + LoRaMacEventInfoStatus_t Status; + LmHandlerMsgTypes_t MsgType; + uint8_t AckReceived; + int8_t Datarate; + uint32_t UplinkCounter; + LmHandlerAppData_t AppData; + int8_t TxPower; + uint8_t Channel; +}LmHandlerTxParams_t; /*! * \brief Rx notification parameters */ typedef struct LmHandlerRxParams_s { - uint8_t IsMcpsIndication; - LoRaMacEventInfoStatus_t Status; - int8_t Datarate; - int8_t Rssi; - int8_t Snr; - uint32_t DownlinkCounter; - int8_t RxSlot; -} LmHandlerRxParams_t; + uint8_t IsMcpsIndication; + LoRaMacEventInfoStatus_t Status; + int8_t Datarate; + int8_t Rssi; + int8_t Snr; + uint32_t DownlinkCounter; + int8_t RxSlot; + bool LinkCheck; + uint8_t DemodMargin; + uint8_t NbGateways; +}LmHandlerRxParams_t; /*! * \brief Beacon notification parameters */ typedef struct LmHandlerBeaconParams_s { - LoRaMacEventInfoStatus_t Status; - LmHandlerBeaconState_t State; - BeaconInfo_t Info; -} LmHandlerBeaconParams_t; + LoRaMacEventInfoStatus_t Status; + LmHandlerBeaconState_t State; + BeaconInfo_t Info; +}LmHandlerBeaconParams_t; /*! * \brief LoRaMac handler parameters */ typedef struct LmHandlerParams_s { - /*! - * Active Region - */ - LoRaMacRegion_t ActiveRegion; - /*! - * Default Class - */ - DeviceClass_t DefaultClass; - /*! - * Holds the ADR state - */ - bool AdrEnable; - /*! - * Uplink datarate, when \ref AdrEnable is OFF - */ - int8_t TxDatarate; - /*! - * LoRaWAN ETSI duty cycle control enable/disable - * - * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes - */ - bool DutyCycleEnabled; - /*! - * Periodicity of the ping slots - */ - uint8_t PingPeriodicity; -} LmHandlerParams_t; + /*! + * Active Region + */ + LoRaMacRegion_t ActiveRegion; + /*! + * Default Class + */ + DeviceClass_t DefaultClass; + /*! + * Holds the ADR state + */ + bool AdrEnable; + /*! + * Uplink datarate, when \ref AdrEnable is OFF + */ + int8_t TxDatarate; + /*! + * Enables/Disables a public network usage + */ + bool PublicNetworkEnable; + /*! + * LoRaWAN ETSI duty cycle control enable/disable + * + * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes + */ + bool DutyCycleEnabled; + /*! + * Application data buffer maximum size + */ + uint8_t DataBufferMaxSize; + /*! + * Application data buffer pointer + */ + uint8_t *DataBuffer; + /*! + * Periodicity of the ping slots + */ + uint8_t PingPeriodicity; +}LmHandlerParams_t; /*! * \brief LoRaMac handler callbacks */ typedef struct LmHandlerCallbacks_s { - /*! - * \brief Get the current battery level - * - * \retval value Battery level ( 0: very low, 254: fully charged ) - */ - uint8_t (*GetBatteryLevel)(void); - /*! - * \brief Get the current temperature - * - * \retval value Temperature in degree Celsius - */ - /*float*/ uint16_t (*GetTemperature)(void); - /*! - * \brief Will be called each time a Radio IRQ is handled by the MAC - * layer. - * - * \warning Runs in a IRQ context. Should only change variables state. - */ - void (*OnMacProcess)(void); - /*! - * \brief Notifies the upper layer that a network has been joined - * - * \param [in] params notification parameters - */ - void (*OnJoinRequest)(LmHandlerJoinParams_t *params); - /*! - * \brief Notifies upper layer that a frame has been transmitted - * - * \param [in] params notification parameters - */ - void (*OnTxData)(LmHandlerTxParams_t *params); - /*! - * \brief Notifies the upper layer that an applicative frame has been received - * - * \param [in] appData Received applicative data - * \param [in] params notification parameters - */ - void (*OnRxData)(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params); -} LmHandlerCallbacks_t; + /*! + * Get the current battery level + * + * \retval value Battery level ( 0: very low, 254: fully charged ) + */ + uint8_t ( *GetBatteryLevel )( void ); + /*! + * Get the current temperature + * + * \retval value Temperature in degree Celsius + */ + /*float*/ uint16_t ( *GetTemperature )( void ); + /*! + * Get the board 64 bits unique ID + * + * \param [OUT] id unique + */ + void (*GetUniqueId)(uint8_t *id); + /*! + * Get the board 32 bits unique ID (LSB) + * + * \retval devAddr Device Address + */ + uint32_t (*GetDevAddr)(void); + /*! + *\brief Will be called each time a Radio IRQ is handled by the MAC + * layer. + * + *\warning Runs in a IRQ context. Should only change variables state. + */ + void ( *OnMacProcess )( void ); + /*! + * Notifies the upper layer that the NVM context has changed + * + * \param [IN] state Indicates if we are storing (true) or + * restoring (false) the NVM context + * + * \param [IN] size Number of data bytes which were stored or restored. + */ + void ( *OnNvmDataChange )( LmHandlerNvmContextStates_t state, uint16_t size ); + /*! + * Notifies the upper layer that a network parameters have been set + * + * \param [IN] params notification parameters + */ + void ( *OnNetworkParametersChange )( CommissioningParams_t *params ); + /*! + * Notifies the upper layer that a network has been joined + * + * \param [IN] params notification parameters + */ + void ( *OnJoinRequest )( LmHandlerJoinParams_t *params ); + /*! + * Notifies upper layer that a frame has been transmitted + * + * \param [IN] params notification parameters + */ + void ( *OnTxData )( LmHandlerTxParams_t *params ); + /*! + * Notifies the upper layer that an applicative frame has been received + * + * \param [IN] appData Received applicative data + * \param [IN] params notification parameters + */ + void ( *OnRxData )( LmHandlerAppData_t *appData, LmHandlerRxParams_t *params ); + /*! + * Confirms the LoRaWAN device class change + * + * \param [IN] deviceClass New end-device class + */ + void ( *OnClassChange )( DeviceClass_t deviceClass ); + /*! + * Notifies the upper layer that the beacon status has changed + * + * \param [IN] params notification parameters + */ + void ( *OnBeaconStatusChange )( LmHandlerBeaconParams_t *params ); + /*! + * Notifies the upper layer that the system time has been updated. + */ + void ( *OnSysTimeUpdate )( void ); +}LmHandlerCallbacks_t; /* External variables --------------------------------------------------------*/ /* Exported macros -----------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ /*! - * \brief LoRaMac handler initialisation + * LoRaMac handler initialisation * * \param [in] handlerCallbacks LoRaMac handler callbacks * * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if package have been * initialized else \ref LORAMAC_HANDLER_ERROR */ -LmHandlerErrorStatus_t LmHandlerInit(LmHandlerCallbacks_t *handlerCallbacks); +LmHandlerErrorStatus_t LmHandlerInit( LmHandlerCallbacks_t *handlerCallbacks ); /*! - * \brief Indicates if the LoRaMacHandler is busy - * + * Indicates if the LoRaMacHandler is busy + * * \retval status [true] Busy, [false] free */ -bool LmHandlerIsBusy(void); +bool LmHandlerIsBusy( void ); /*! - * \brief Processes the LoRaMac and Radio events. When no pendig operation asks to go in low power mode. + * Processes the LoRaMac and Radio events. + * When no pendig operation asks to go in low power mode. * * \remark This function must be called in the main loop. */ -void LmHandlerProcess(void); +void LmHandlerProcess( void ); /*! - * \brief Instructs the MAC layer to send a ClassA uplink + * Instructs the MAC layer to send a ClassA uplink * - * \param [in] appData Data to be sent - * \param [in] isTxConfirmed Indicates if the uplink requires an acknowledgement + * \param [IN] appData Data to be sent + * \param [IN] isTxConfirmed Indicates if the uplink requires an acknowledgement * \param [out] nextTxIn Time before next uplink window available * \param [in] allowDelayedTx when set to true, the frame will be delayed * * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been * processed else \ref LORAMAC_HANDLER_ERROR */ -LmHandlerErrorStatus_t LmHandlerSend(LmHandlerAppData_t *appData, LmHandlerMsgTypes_t isTxConfirmed, - TimerTime_t *nextTxIn, bool allowDelayedTx); +LmHandlerErrorStatus_t LmHandlerSend( LmHandlerAppData_t *appData, LmHandlerMsgTypes_t isTxConfirmed, + TimerTime_t *nextTxIn, bool allowDelayedTx ); /*! * \brief Check whether the Device is joined to the network @@ -280,7 +340,7 @@ LmHandlerErrorStatus_t LmHandlerPackageRegister(uint8_t id, void *params); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetCurrentClass(DeviceClass_t *deviceClass); +LmHandlerErrorStatus_t LmHandlerGetCurrentClass(DeviceClass_t *deviceClass); /*! * \brief Gets the LoRaWAN Device EUI (if OTAA) @@ -290,7 +350,7 @@ int32_t LmHandlerGetCurrentClass(DeviceClass_t *deviceClass); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetDevEUI(uint8_t *devEUI); +LmHandlerErrorStatus_t LmHandlerGetDevEUI(uint8_t *devEUI); /*! * \brief Sets the LoRaWAN Device EUI (if OTAA) @@ -300,17 +360,17 @@ int32_t LmHandlerGetDevEUI(uint8_t *devEUI); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetDevEUI(uint8_t *devEUI); +LmHandlerErrorStatus_t LmHandlerSetDevEUI(uint8_t *devEUI); /*! - * \brief Gets the LoRaWAN AppEUI (from the Commissionning) + * \brief Gets the LoRaWAN AppEUI (from the Commissioning) * * \param [out] appEUI LoRaWAN AppEUI * * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetAppEUI(uint8_t *appEUI); +LmHandlerErrorStatus_t LmHandlerGetAppEUI(uint8_t *appEUI); /*! * \brief Sets the LoRaWAN App EUI (if OTAA) @@ -320,17 +380,17 @@ int32_t LmHandlerGetAppEUI(uint8_t *appEUI); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetAppEUI(uint8_t *appEUI); +LmHandlerErrorStatus_t LmHandlerSetAppEUI(uint8_t *appEUI); /*! - * \brief Gets the LoRaWAN Network ID (from the Commissionning if ABP or after the Join if OTAA) + * \brief Gets the LoRaWAN Network ID (from the Commissioning if ABP or after the Join if OTAA) * * \param [out] networkId current network ID * * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetNetworkID(uint32_t *networkId); +LmHandlerErrorStatus_t LmHandlerGetNetworkID(uint32_t *networkId); /*! * \brief Sets the LoRaWAN Network ID @@ -340,17 +400,17 @@ int32_t LmHandlerGetNetworkID(uint32_t *networkId); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetNetworkID(uint32_t networkId); +LmHandlerErrorStatus_t LmHandlerSetNetworkID(uint32_t networkId); /*! - * \brief Gets the LoRaWAN Device Address (from the Commissionning if ABP or after the Join if OTAA) + * \brief Gets the LoRaWAN Device Address (from the Commissioning if ABP or after the Join if OTAA) * * \param [out] devAddr current device address * * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetDevAddr(uint32_t *devAddr); +LmHandlerErrorStatus_t LmHandlerGetDevAddr(uint32_t *devAddr); /*! * \brief Sets the LoRaWAN Device Address (if ABP) @@ -360,7 +420,7 @@ int32_t LmHandlerGetDevAddr(uint32_t *devAddr); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetDevAddr(uint32_t devAddr); +LmHandlerErrorStatus_t LmHandlerSetDevAddr(uint32_t devAddr); /*! * \brief Gets the current active region @@ -370,7 +430,7 @@ int32_t LmHandlerSetDevAddr(uint32_t devAddr); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetActiveRegion(LoRaMacRegion_t *region); +LmHandlerErrorStatus_t LmHandlerGetActiveRegion(LoRaMacRegion_t *region); /*! * \brief Sets the current active region @@ -380,7 +440,7 @@ int32_t LmHandlerGetActiveRegion(LoRaMacRegion_t *region); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetActiveRegion(LoRaMacRegion_t region); +LmHandlerErrorStatus_t LmHandlerSetActiveRegion(LoRaMacRegion_t region); /*! * \brief Gets the Adaptive data rate (1 = the Network manages the DR, 0 = the device manages the DR) @@ -390,7 +450,7 @@ int32_t LmHandlerSetActiveRegion(LoRaMacRegion_t region); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetAdrEnable(bool *adrEnable); +LmHandlerErrorStatus_t LmHandlerGetAdrEnable(bool *adrEnable); /*! * \brief Sets the Adaptive data rate (1 = the Network manages the DR, 0 = the device manages the DR) @@ -400,7 +460,7 @@ int32_t LmHandlerGetAdrEnable(bool *adrEnable); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetAdrEnable(bool adrEnable); +LmHandlerErrorStatus_t LmHandlerSetAdrEnable(bool adrEnable); /*! * \brief Gets the current datarate @@ -410,7 +470,7 @@ int32_t LmHandlerSetAdrEnable(bool adrEnable); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetTxDatarate(int8_t *txDatarate); +LmHandlerErrorStatus_t LmHandlerGetTxDatarate(int8_t *txDatarate); /*! * \brief Sets the current datarate @@ -420,7 +480,7 @@ int32_t LmHandlerGetTxDatarate(int8_t *txDatarate); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetTxDatarate(int8_t txDatarate); +LmHandlerErrorStatus_t LmHandlerSetTxDatarate(int8_t txDatarate); /*! * \brief Gets the duty cycle flag @@ -430,7 +490,7 @@ int32_t LmHandlerSetTxDatarate(int8_t txDatarate); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetDutyCycleEnable(bool *dutyCycleEnable); +LmHandlerErrorStatus_t LmHandlerGetDutyCycleEnable(bool *dutyCycleEnable); /*! * \brief Sets the current datarate @@ -440,7 +500,7 @@ int32_t LmHandlerGetDutyCycleEnable(bool *dutyCycleEnable); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetDutyCycleEnable(bool dutyCycleEnable); +LmHandlerErrorStatus_t LmHandlerSetDutyCycleEnable(bool dutyCycleEnable); /*! * \brief Gets the current RX_2 datarate and frequency @@ -450,7 +510,7 @@ int32_t LmHandlerSetDutyCycleEnable(bool dutyCycleEnable); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetRX2Params(RxChannelParams_t *rxParams); +LmHandlerErrorStatus_t LmHandlerGetRX2Params(RxChannelParams_t *rxParams); /*! * \brief Gets the current TX power @@ -460,7 +520,7 @@ int32_t LmHandlerGetRX2Params(RxChannelParams_t *rxParams); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetTxPower(int8_t *txPower); +LmHandlerErrorStatus_t LmHandlerGetTxPower(int8_t *txPower); /*! * \brief Gets the current RX1 delay (after the TX done) @@ -470,7 +530,7 @@ int32_t LmHandlerGetTxPower(int8_t *txPower); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetRx1Delay(uint32_t *rxDelay); +LmHandlerErrorStatus_t LmHandlerGetRx1Delay(uint32_t *rxDelay); /*! * \brief Gets the current RX2 delay (after the TX done) @@ -480,7 +540,7 @@ int32_t LmHandlerGetRx1Delay(uint32_t *rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetRx2Delay(uint32_t *rxDelay); +LmHandlerErrorStatus_t LmHandlerGetRx2Delay(uint32_t *rxDelay); /*! * \brief Gets the current RX1 Join delay (after the TX done) @@ -490,7 +550,7 @@ int32_t LmHandlerGetRx2Delay(uint32_t *rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetJoinRx1Delay(uint32_t *rxDelay); +LmHandlerErrorStatus_t LmHandlerGetJoinRx1Delay(uint32_t *rxDelay); /*! * \brief Gets the current RX2 Join delay (after the TX done) @@ -500,7 +560,7 @@ int32_t LmHandlerGetJoinRx1Delay(uint32_t *rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetJoinRx2Delay(uint32_t *rxDelay); +LmHandlerErrorStatus_t LmHandlerGetJoinRx2Delay(uint32_t *rxDelay); /*! * \brief Sets the RX_2 datarate and frequency @@ -510,7 +570,7 @@ int32_t LmHandlerGetJoinRx2Delay(uint32_t *rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetRX2Params(RxChannelParams_t *rxParams); +LmHandlerErrorStatus_t LmHandlerSetRX2Params(RxChannelParams_t *rxParams); /*! * \brief Sets the TX power @@ -520,7 +580,7 @@ int32_t LmHandlerSetRX2Params(RxChannelParams_t *rxParams); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetTxPower(int8_t txPower); +LmHandlerErrorStatus_t LmHandlerSetTxPower(int8_t txPower); /*! * \brief Sets the RX1 delay (after the TX done) @@ -530,7 +590,7 @@ int32_t LmHandlerSetTxPower(int8_t txPower); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetRx1Delay(uint32_t rxDelay); +LmHandlerErrorStatus_t LmHandlerSetRx1Delay(uint32_t rxDelay); /*! * \brief Sets the RX2 delay (after the TX done) @@ -540,7 +600,7 @@ int32_t LmHandlerSetRx1Delay(uint32_t rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetRx2Delay(uint32_t rxDelay); +LmHandlerErrorStatus_t LmHandlerSetRx2Delay(uint32_t rxDelay); /*! * \brief Sets the RX1 delay (after the TX done) @@ -550,7 +610,7 @@ int32_t LmHandlerSetRx2Delay(uint32_t rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetJoinRx1Delay(uint32_t rxDelay); +LmHandlerErrorStatus_t LmHandlerSetJoinRx1Delay(uint32_t rxDelay); /*! * \brief Sets the RX2 delay (after the TX done) @@ -560,7 +620,7 @@ int32_t LmHandlerSetJoinRx1Delay(uint32_t rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetJoinRx2Delay(uint32_t rxDelay); +LmHandlerErrorStatus_t LmHandlerSetJoinRx2Delay(uint32_t rxDelay); /*! * \brief Gets the current ClassB Ping periodicity @@ -570,7 +630,7 @@ int32_t LmHandlerSetJoinRx2Delay(uint32_t rxDelay); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetPingPeriodicity(uint8_t *pingPeriodicity); +LmHandlerErrorStatus_t LmHandlerGetPingPeriodicity(uint8_t *pingPeriodicity); /*! * \brief Sets the ClassB Ping periodicity @@ -580,7 +640,7 @@ int32_t LmHandlerGetPingPeriodicity(uint8_t *pingPeriodicity); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerSetPingPeriodicity(uint8_t pingPeriodicity); +LmHandlerErrorStatus_t LmHandlerSetPingPeriodicity(uint8_t pingPeriodicity); /*! * \brief Gets the current ClassB Beacon status @@ -590,8 +650,103 @@ int32_t LmHandlerSetPingPeriodicity(uint8_t pingPeriodicity); * \retval -1 LORAMAC_HANDLER_ERROR * 0 LORAMAC_HANDLER_SUCCESS */ -int32_t LmHandlerGetBeaconState(BeaconState_t *beaconState); +LmHandlerErrorStatus_t LmHandlerGetBeaconState(BeaconState_t *beaconState); + +/*! + * \brief Gets the LoRaWAN NwkKey (from the se-identity) + * + * \param [out] nwkKey LoRaWAN NwkKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerGetNwkKey( uint8_t *nwkKey ); + +/*! + * \brief Sets the LoRaWAN NwkKey (if OTAA) + * + * \param [in] nwkKey LoRaWAN NwkKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerSetNwkKey( uint8_t *nwkKey ); + +/*! + * \brief Gets the LoRaWAN AppKey (from the se-identity) + * + * \param [out] appKey LoRaWAN AppKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerGetAppKey( uint8_t *appKey ); +/*! + * \brief Sets the LoRaWAN AppKey (if OTAA) + * + * \param [in] appKey LoRaWAN AppKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerSetAppKey( uint8_t *appKey ); + +/*! + * \brief Gets the LoRaWAN NwkSKey (from the se-identity) + * + * \param [out] nwkSKey LoRaWAN NwkSKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerGetNwkSKey( uint8_t *nwkSKey ); + +/*! + * \brief Sets the LoRaWAN NwkSKey (if OTAA) + * + * \param [in] nwkSKey LoRaWAN NwkSKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerSetNwkSKey( uint8_t *nwkSKey ); + +/*! + * \brief Gets the LoRaWAN AppSKey (from the se-identity) + * + * \param [out] appSKey LoRaWAN AppSKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerGetAppSKey( uint8_t *appSKey ); + +/*! + * \brief Sets the LoRaWAN AppSKey (if OTAA) + * + * \param [in] appSKey appSKey LoRaWAN AppSKey + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerSetAppSKey( uint8_t *appSKey ); + +/*! + * Requests network server time update + * + * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been + * processed else \ref LORAMAC_HANDLER_ERROR + */ +LmHandlerErrorStatus_t LmHandlerDeviceTimeReq( void ); + +/*! + * Requests Link connectivity check + * + * \retval -1 LORAMAC_HANDLER_ERROR + * 0 LORAMAC_HANDLER_SUCCESS + */ +LmHandlerErrorStatus_t LmHandlerLinkCheckReq( void ); #ifdef __cplusplus } #endif diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandlerTypes.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandlerTypes.h index 1292eca1..9cf0b693 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandlerTypes.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/LmHandlerTypes.h @@ -31,10 +31,6 @@ #ifndef __LORAMAC_HANDLER_TYPES_H__ #define __LORAMAC_HANDLER_TYPES_H__ -#ifdef __cplusplus -extern "C" { -#endif - /* Includes ------------------------------------------------------------------*/ #include "LoRaMac.h" @@ -46,104 +42,100 @@ extern "C" { */ typedef enum { - LORAMAC_HANDLER_ADR_OFF = 0, - LORAMAC_HANDLER_ADR_ON = !LORAMAC_HANDLER_ADR_OFF -} LmHandlerAdrStates_t; + LORAMAC_HANDLER_ADR_OFF = 0, + LORAMAC_HANDLER_ADR_ON = !LORAMAC_HANDLER_ADR_OFF +}LmHandlerAdrStates_t; /*! * */ typedef enum { - LORAMAC_HANDLER_RESET = 0, - LORAMAC_HANDLER_SET = !LORAMAC_HANDLER_RESET -} LmHandlerFlagStatus_t; + LORAMAC_HANDLER_RESET = 0, + LORAMAC_HANDLER_SET = !LORAMAC_HANDLER_RESET +}LmHandlerFlagStatus_t; /*! * */ typedef enum { - LORAMAC_HANDLER_ERROR = -1, - LORAMAC_HANDLER_BUSY_ERROR = -2, - LORAMAC_HANDLER_NO_NETWORK_JOINED = -3, - LORAMAC_HANDLER_COMPLIANCE_RUNNING = -4, - LORAMAC_HANDLER_CRYPTO_ERROR = -5, - LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED = -6, - LORAMAC_HANDLER_SUCCESS = 0 -} LmHandlerErrorStatus_t; + LORAMAC_HANDLER_ERROR = -1, + LORAMAC_HANDLER_BUSY_ERROR = -2, + LORAMAC_HANDLER_NO_NETWORK_JOINED = -3, + LORAMAC_HANDLER_COMPLIANCE_RUNNING = -4, + LORAMAC_HANDLER_CRYPTO_ERROR = -5, + LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED = -6, + LORAMAC_HANDLER_SUCCESS = 0 +}LmHandlerErrorStatus_t; /*! * */ typedef enum { - LORAMAC_HANDLER_UNCONFIRMED_MSG = 0, - LORAMAC_HANDLER_CONFIRMED_MSG = !LORAMAC_HANDLER_UNCONFIRMED_MSG -} LmHandlerMsgTypes_t; + LORAMAC_HANDLER_UNCONFIRMED_MSG = 0, + LORAMAC_HANDLER_CONFIRMED_MSG = !LORAMAC_HANDLER_UNCONFIRMED_MSG +}LmHandlerMsgTypes_t; /*! * */ typedef enum { - LORAMAC_HANDLER_FALSE = 0, - LORAMAC_HANDLER_TRUE = !LORAMAC_HANDLER_FALSE -} LmHandlerBoolean_t; + LORAMAC_HANDLER_FALSE = 0, + LORAMAC_HANDLER_TRUE = !LORAMAC_HANDLER_FALSE +}LmHandlerBoolean_t; typedef enum { - LORAMAC_HANDLER_BEACON_ACQUIRING, - LORAMAC_HANDLER_BEACON_LOST, - LORAMAC_HANDLER_BEACON_RX, - LORAMAC_HANDLER_BEACON_NRX -} LmHandlerBeaconState_t; + LORAMAC_HANDLER_BEACON_ACQUIRING, + LORAMAC_HANDLER_BEACON_LOST, + LORAMAC_HANDLER_BEACON_RX, + LORAMAC_HANDLER_BEACON_NRX +}LmHandlerBeaconState_t; typedef enum { - LORAMAC_HANDLER_NVM_RESTORE, - LORAMAC_HANDLER_NVM_STORE, -} LmHandlerNvmContextStates_t; + LORAMAC_HANDLER_NVM_RESTORE, + LORAMAC_HANDLER_NVM_STORE, +}LmHandlerNvmContextStates_t; /*! * Commissioning parameters */ typedef struct CommissioningParams_s { - uint8_t DevEui[8]; - uint8_t JoinEui[8]; - uint32_t NetworkId; - uint32_t DevAddr; -} CommissioningParams_t; + uint8_t DevEui[8]; + uint8_t JoinEui[8]; + uint32_t NetworkId; + uint32_t DevAddr; +}CommissioningParams_t; /*! * Application data structure */ typedef struct LmHandlerAppData_s { - uint8_t Port; - uint8_t BufferSize; - uint8_t *Buffer; -} LmHandlerAppData_t; + uint8_t Port; + uint8_t BufferSize; + uint8_t *Buffer; +}LmHandlerAppData_t; typedef struct LmHandlerRequestParams_s { - uint8_t IsMcpsRequest; - LoRaMacStatus_t Status; - union - { - Mcps_t Mcps; - Mlme_t Mlme; - } RequestType; -} LmHandlerRequestParams_t; + uint8_t IsMcpsRequest; + LoRaMacStatus_t Status; + union + { + Mcps_t Mcps; + Mlme_t Mlme; + }RequestType; +}LmHandlerRequestParams_t; /* External variables --------------------------------------------------------*/ /* Exported macros -----------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ -#ifdef __cplusplus -} -#endif - #endif /* __LORAMAC_HANDLER_TYPES_H__ */ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmCtxMgmt.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmCtxMgmt.c deleted file mode 100644 index f360fb59..00000000 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmCtxMgmt.c +++ /dev/null @@ -1,400 +0,0 @@ -/*! - * \file NvmCtxMgmt.c - * - * \brief NVM context management implementation - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2013-2017 Semtech - * - * ___ _____ _ ___ _ _____ ___ ___ ___ ___ - * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| - * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| - * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| - * embedded.connectivity.solutions=============== - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - * - * \author Gregory Cristian ( Semtech ) - * - * \author Daniel Jaeckle ( STACKFORCE ) - * - * \author Johannes Bruder ( STACKFORCE ) - */ -/** - ****************************************************************************** - * - * Portions COPYRIGHT 2020 STMicroelectronics - * - * @file NvmCtxMgmt.c - * @author MCD Application Team - * @brief NVM Context Management definition - ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ -#include "NvmCtxMgmt.h" - -/* Private typedef -----------------------------------------------------------*/ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) -/*! - * LoRaMAC Structure holding contexts changed status - * in case of a \ref MLME_NVM_CTXS_UPDATE indication. - */ -typedef union uLoRaMacCtxsUpdateInfo -{ - /*! - * Byte-access to the bits - */ - uint8_t Value; - /*! - * The according context bit will be set to one - * if the context changed or 0 otherwise. - */ - struct sElements - { - /*! - * Mac core nvm context - */ - uint8_t Mac : 1; - /*! - * Region module nvm contexts - */ - uint8_t Region : 1; - /*! - * Crypto module context - */ - uint8_t Crypto : 1; - /*! - * Secure Element driver context - */ - uint8_t SecureElement : 1; - /*! - * MAC commands module context - */ - uint8_t Commands : 1; - /*! - * Class B module context - */ - uint8_t ClassB : 1; - /*! - * Confirm queue module context - */ - uint8_t ConfirmQueue : 1; - /*! - * FCnt Handler module context - */ - uint8_t FCntHandlerNvmCtx : 1; - } Elements; -} LoRaMacCtxUpdateStatus_t; -#endif /* CONTEXT_MANAGEMENT_ENABLED == 1 */ - -/* Private define ------------------------------------------------------------*/ -/*! - * Enables/Disables the context storage management storage at all. Must be enabled for LoRaWAN 1.1.x. - * WARNING: Still under development and not tested yet. - */ -#define CONTEXT_MANAGEMENT_ENABLED 0 - -/*! - * Enables/Disables maximum persistent context storage management. All module contexts will be saved on a non-volatile memory. - * WARNING: Still under development and not tested yet. - */ -#define MAX_PERSISTENT_CTX_MGMT_ENABLED 0 - -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) -#define NVM_CTX_STORAGE_MASK 0xFF -#else /* MAX_PERSISTENT_CTX_MGMT_ENABLED == 0 */ -#define NVM_CTX_STORAGE_MASK 0x8C -#endif /* MAX_PERSISTENT_CTX_MGMT_ENABLED */ - -/* Private macro -------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) -static LoRaMacCtxUpdateStatus_t CtxUpdateStatus = { .Value = 0 }; - -/* - * Nvmm handles - */ -static NvmmDataBlock_t SecureElementNvmCtxDataBlock; -static NvmmDataBlock_t CryptoNvmCtxDataBlock; -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) -static NvmmDataBlock_t MacNvmCtxDataBlock; -static NvmmDataBlock_t RegionNvmCtxDataBlock; -static NvmmDataBlock_t CommandsNvmCtxDataBlock; -static NvmmDataBlock_t ConfirmQueueNvmCtxDataBlock; -static NvmmDataBlock_t ClassBNvmCtxDataBlock; -#endif /* MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 */ -#endif /* CONTEXT_MANAGEMENT_ENABLED == 1 */ - -/* Exported functions ---------------------------------------------------------*/ -void NvmCtxMgmtEvent(LoRaMacNvmCtxModule_t module) -{ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) - switch (module) - { - case LORAMAC_NVMCTXMODULE_MAC: - { - CtxUpdateStatus.Elements.Mac = 1; - break; - } - case LORAMAC_NVMCTXMODULE_REGION: - { - CtxUpdateStatus.Elements.Region = 1; - break; - } - case LORAMAC_NVMCTXMODULE_CRYPTO: - { - CtxUpdateStatus.Elements.Crypto = 1; - break; - } - case LORAMAC_NVMCTXMODULE_SECURE_ELEMENT: - { - CtxUpdateStatus.Elements.SecureElement = 1; - break; - } - case LORAMAC_NVMCTXMODULE_COMMANDS: - { - CtxUpdateStatus.Elements.Commands = 1; - break; - } - case LORAMAC_NVMCTXMODULE_CLASS_B: - { - CtxUpdateStatus.Elements.ClassB = 1; - break; - } - case LORAMAC_NVMCTXMODULE_CONFIRM_QUEUE: - { - CtxUpdateStatus.Elements.ConfirmQueue = 1; - break; - } - default: - { - break; - } - } -#endif /* CONTEXT_MANAGEMENT_ENABLED == 1 */ -} - -NvmCtxMgmtStatus_t NvmCtxMgmtStore(void) -{ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) - /* Read out the contexts lengths and pointers */ - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_NVM_CTXS; - LoRaMacMibGetRequestConfirm(&mibReq); - LoRaMacCtxs_t *MacContexts = mibReq.Param.Contexts; - - /* Input checks */ - if ((CtxUpdateStatus.Value & NVM_CTX_STORAGE_MASK) == 0) - { - return NVMCTXMGMT_STATUS_FAIL; - } - if (LoRaMacStop() != LORAMAC_STATUS_OK) - { - return NVMCTXMGMT_STATUS_FAIL; - } - - /* Write */ - if (CtxUpdateStatus.Elements.Crypto == 1) - { - if (NvmmWrite(&CryptoNvmCtxDataBlock, MacContexts->CryptoNvmCtx, MacContexts->CryptoNvmCtxSize) != NVMM_SUCCESS) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if (CtxUpdateStatus.Elements.SecureElement == 1) - { - if (NvmmWrite(&SecureElementNvmCtxDataBlock, MacContexts->SecureElementNvmCtx, - MacContexts->SecureElementNvmCtxSize) != NVMM_SUCCESS) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) - if (CtxUpdateStatus.Elements.Mac == 1) - { - if (NvmmWrite(&MacNvmCtxDataBlock, MacContexts->MacNvmCtx, MacContexts->MacNvmCtxSize) != NVMM_SUCCESS) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if (CtxUpdateStatus.Elements.Region == 1) - { - if (NvmmWrite(&RegionNvmCtxDataBlock, MacContexts->RegionNvmCtx, MacContexts->RegionNvmCtxSize) != NVMM_SUCCESS) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if (CtxUpdateStatus.Elements.Commands == 1) - { - if (NvmmWrite(&CommandsNvmCtxDataBlock, MacContexts->CommandsNvmCtx, MacContexts->CommandsNvmCtxSize) != NVMM_SUCCESS) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if (CtxUpdateStatus.Elements.ClassB == 1) - { - if (NvmmWrite(&ClassBNvmCtxDataBlock, MacContexts->ClassBNvmCtx, MacContexts->ClassBNvmCtxSize) != NVMM_SUCCESS) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if (CtxUpdateStatus.Elements.ConfirmQueue == 1) - { - if (NvmmWrite(&ConfirmQueueNvmCtxDataBlock, MacContexts->ConfirmQueueNvmCtx, - MacContexts->ConfirmQueueNvmCtxSize) != NVMM_SUCCESS) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } -#endif /* MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 */ - - CtxUpdateStatus.Value = 0x00; - - /* Resume LoRaMac */ - LoRaMacStart(); - - return NVMCTXMGMT_STATUS_SUCCESS; -#else /* CONTEXT_MANAGEMENT_ENABLED == 0 */ - return NVMCTXMGMT_STATUS_FAIL; -#endif /* CONTEXT_MANAGEMENT_ENABLED */ -} - -NvmCtxMgmtStatus_t NvmCtxMgmtRestore(void) -{ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) - MibRequestConfirm_t mibReq; - LoRaMacCtxs_t contexts = { 0 }; - NvmCtxMgmtStatus_t status = NVMCTXMGMT_STATUS_SUCCESS; - - /* Read out the contexts lengths */ - mibReq.Type = MIB_NVM_CTXS; - LoRaMacMibGetRequestConfirm(&mibReq); - - - uint8_t NvmCryptoCtxRestore[mibReq.Param.Contexts->CryptoNvmCtxSize]; - uint8_t NvmSecureElementCtxRestore[mibReq.Param.Contexts->SecureElementNvmCtxSize]; -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) - uint8_t NvmMacCtxRestore[mibReq.Param.Contexts->MacNvmCtxSize]; - uint8_t NvmRegionCtxRestore[mibReq.Param.Contexts->RegionNvmCtxSize]; - uint8_t NvmCommandsCtxRestore[mibReq.Param.Contexts->CommandsNvmCtxSize]; - uint8_t NvmClassBCtxRestore[mibReq.Param.Contexts->ClassBNvmCtxSize]; - uint8_t NvmConfirmQueueCtxRestore[mibReq.Param.Contexts->ConfirmQueueNvmCtxSize]; -#endif /* MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 */ - - if (NvmmDeclare(&CryptoNvmCtxDataBlock, mibReq.Param.Contexts->CryptoNvmCtxSize) == NVMM_SUCCESS) - { - NvmmRead(&CryptoNvmCtxDataBlock, NvmCryptoCtxRestore, mibReq.Param.Contexts->CryptoNvmCtxSize); - contexts.CryptoNvmCtx = &NvmCryptoCtxRestore; - contexts.CryptoNvmCtxSize = mibReq.Param.Contexts->CryptoNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if (NvmmDeclare(&SecureElementNvmCtxDataBlock, mibReq.Param.Contexts->SecureElementNvmCtxSize) == NVMM_SUCCESS) - { - NvmmRead(&SecureElementNvmCtxDataBlock, NvmSecureElementCtxRestore, mibReq.Param.Contexts->SecureElementNvmCtxSize); - contexts.SecureElementNvmCtx = &NvmSecureElementCtxRestore; - contexts.SecureElementNvmCtxSize = mibReq.Param.Contexts->SecureElementNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) - if (NvmmDeclare(&MacNvmCtxDataBlock, mibReq.Param.Contexts->MacNvmCtxSize) == NVMM_SUCCESS) - { - NvmmRead(&MacNvmCtxDataBlock, NvmMacCtxRestore, mibReq.Param.Contexts->MacNvmCtxSize); - contexts.MacNvmCtx = &NvmMacCtxRestore; - contexts.MacNvmCtxSize = mibReq.Param.Contexts->MacNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if (NvmmDeclare(&RegionNvmCtxDataBlock, mibReq.Param.Contexts->RegionNvmCtxSize) == NVMM_SUCCESS) - { - NvmmRead(&RegionNvmCtxDataBlock, NvmRegionCtxRestore, mibReq.Param.Contexts->RegionNvmCtxSize); - contexts.RegionNvmCtx = &NvmRegionCtxRestore; - contexts.RegionNvmCtxSize = mibReq.Param.Contexts->RegionNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if (NvmmDeclare(&CommandsNvmCtxDataBlock, mibReq.Param.Contexts->CommandsNvmCtxSize) == NVMM_SUCCESS) - { - NvmmRead(&CommandsNvmCtxDataBlock, NvmCommandsCtxRestore, mibReq.Param.Contexts->CommandsNvmCtxSize); - contexts.CommandsNvmCtx = &NvmCommandsCtxRestore; - contexts.CommandsNvmCtxSize = mibReq.Param.Contexts->CommandsNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if (NvmmDeclare(&ClassBNvmCtxDataBlock, mibReq.Param.Contexts->ClassBNvmCtxSize) == NVMM_SUCCESS) - { - NvmmRead(&ClassBNvmCtxDataBlock, NvmClassBCtxRestore, mibReq.Param.Contexts->ClassBNvmCtxSize); - contexts.ClassBNvmCtx = &NvmClassBCtxRestore; - contexts.ClassBNvmCtxSize = mibReq.Param.Contexts->ClassBNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if (NvmmDeclare(&ConfirmQueueNvmCtxDataBlock, mibReq.Param.Contexts->ConfirmQueueNvmCtxSize) == NVMM_SUCCESS) - { - NvmmRead(&ConfirmQueueNvmCtxDataBlock, NvmConfirmQueueCtxRestore, mibReq.Param.Contexts->ConfirmQueueNvmCtxSize); - contexts.ConfirmQueueNvmCtx = &NvmConfirmQueueCtxRestore; - contexts.ConfirmQueueNvmCtxSize = mibReq.Param.Contexts->ConfirmQueueNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } -#endif /* MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 */ - - /* Enforce storing all contexts */ - if (status == NVMCTXMGMT_STATUS_FAIL) - { - CtxUpdateStatus.Value = 0xFF; - NvmCtxMgmtStore(); - } - else - { - /* If successful query the mac to restore contexts */ - mibReq.Type = MIB_NVM_CTXS; - mibReq.Param.Contexts = &contexts; - LoRaMacMibSetRequestConfirm(&mibReq); - } - - return status; -#else /* CONTEXT_MANAGEMENT_ENABLED == 0 */ - return NVMCTXMGMT_STATUS_FAIL; -#endif /* CONTEXT_MANAGEMENT_ENABLED */ -} - -/* Private functions ---------------------------------------------------------*/ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmCtxMgmt.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmCtxMgmt.h deleted file mode 100644 index 9b38879c..00000000 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmCtxMgmt.h +++ /dev/null @@ -1,97 +0,0 @@ -/*! - * \file NvmCtxMgmt.h - * - * \brief NVM context management implementation - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2013-2017 Semtech - * - * ___ _____ _ ___ _ _____ ___ ___ ___ ___ - * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| - * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| - * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| - * embedded.connectivity.solutions=============== - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - * - * \author Gregory Cristian ( Semtech ) - * - * \author Daniel Jaeckle ( STACKFORCE ) - * - * \author Johannes Bruder ( STACKFORCE ) - * - * \defgroup NVMCTXMGMT NVM context management implementation - * This module implements the NVM context handling - * \{ - */ -/** - ****************************************************************************** - * - * Portions COPYRIGHT 2020 STMicroelectronics - * - * @file NvmCtxMgmt.h - * @author MCD Application Team - * @brief Header for NVM Context Management module - ****************************************************************************** - */ -#ifndef __NVMCTXMGMT_H__ -#define __NVMCTXMGMT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "LoRaMac.h" - -/* Exported defines ----------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/*! - * Data structure containing the status of a operation - */ -typedef enum NvmCtxMgmtStatus_e -{ - /*! - * Operation was successful - */ - NVMCTXMGMT_STATUS_SUCCESS, - /*! - * Operation was not successful - */ - NVMCTXMGMT_STATUS_FAIL -} NvmCtxMgmtStatus_t; - -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -/*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext Pointer to the function parameters. - * - */ -void NvmCtxMgmtEvent(LoRaMacNvmCtxModule_t module); - -NvmCtxMgmtStatus_t NvmCtxMgmtStore(void); - -NvmCtxMgmtStatus_t NvmCtxMgmtRestore(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* __NVMCTXMGMT_H__ */ - -/*! \} defgroup NVMCTXMGMT */ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmDataMgmt.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmDataMgmt.c new file mode 100644 index 00000000..eaa49d51 --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmDataMgmt.c @@ -0,0 +1,275 @@ +/*! + * \file NvmDataMgmt.c + * + * \brief NVM context management implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \author Johannes Bruder ( STACKFORCE ) + */ + +#include +#include "utilities.h" +#include "LoRaMac.h" +#include "NvmDataMgmt.h" +/*! + * Enables/Disables the context storage management storage. + * Must be enabled for LoRaWAN 1.0.4 or later. + */ +#ifndef CONTEXT_MANAGEMENT_ENABLED +#define CONTEXT_MANAGEMENT_ENABLED 0 +#endif + +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) +#include "nvmm.h" + +static uint16_t NvmNotifyFlags = 0; +#endif /* CONTEXT_MANAGEMENT_ENABLED == 1 */ + +void NvmDataMgmtEvent( uint16_t notifyFlags ) +{ +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) + NvmNotifyFlags = notifyFlags; +#endif /* CONTEXT_MANAGEMENT_ENABLED == 1 */ +} + +uint16_t NvmDataMgmtStore( void ) +{ +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) + uint16_t offset = 0; + uint16_t dataSize = 0; + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NVM_CTXS; + LoRaMacMibGetRequestConfirm( &mibReq ); + LoRaMacNvmData_t* nvm = mibReq.Param.Contexts; + + // Input checks + if( NvmNotifyFlags == LORAMAC_NVM_NOTIFY_FLAG_NONE ) + { + // There was no update. + return 0; + } + if( LoRaMacStop( ) != LORAMAC_STATUS_OK ) + { + return 0; + } + + // Crypto + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_CRYPTO ) == + LORAMAC_NVM_NOTIFY_FLAG_CRYPTO ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->Crypto, sizeof( nvm->Crypto ), + offset ); + } + offset += sizeof( nvm->Crypto ); + + // MacGroup1 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 ) == + LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->MacGroup1, + sizeof( nvm->MacGroup1 ), offset ); + } + offset += sizeof( nvm->MacGroup1 ); + + // MacGroup2 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 ) == + LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->MacGroup2, + sizeof( nvm->MacGroup2 ), offset ); + } + offset += sizeof( nvm->MacGroup2 ); + + // Secure element + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT ) == + LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->SecureElement, sizeof( nvm->SecureElement ), + offset ); + } + offset += sizeof( nvm->SecureElement ); + + // Region group 1 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 ) == + LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->RegionGroup1, + sizeof( nvm->RegionGroup1 ), offset ); + } + offset += sizeof( nvm->RegionGroup1 ); + + // Region group 2 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 ) == + LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->RegionGroup2, + sizeof( nvm->RegionGroup2 ), offset ); + } + offset += sizeof( nvm->RegionGroup2 ); + + // Class b + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_CLASS_B ) == + LORAMAC_NVM_NOTIFY_FLAG_CLASS_B ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->ClassB, sizeof( nvm->ClassB ), + offset ); + } + offset += sizeof( nvm->ClassB ); + + // Reset notification flags + NvmNotifyFlags = LORAMAC_NVM_NOTIFY_FLAG_NONE; + + // Resume LoRaMac + LoRaMacStart( ); + return dataSize; +#else + return 0; +#endif +} + +uint16_t NvmDataMgmtRestore( void ) +{ +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NVM_CTXS; + LoRaMacMibGetRequestConfirm( &mibReq ); + LoRaMacNvmData_t* nvm = mibReq.Param.Contexts; + uint16_t offset = 0; + + // Crypto + if( NvmmCrc32Check( sizeof( LoRaMacCryptoNvmData_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacCryptoNvmData_t ); + + // Mac Group 1 + if( NvmmCrc32Check( sizeof( LoRaMacNvmDataGroup1_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacNvmDataGroup1_t ); + + // Mac Group 2 + if( NvmmCrc32Check( sizeof( LoRaMacNvmDataGroup2_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacNvmDataGroup2_t ); + + // Secure element + if( NvmmCrc32Check( sizeof( SecureElementNvmData_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( SecureElementNvmData_t ); + + // Region group 1 + if( NvmmCrc32Check( sizeof( RegionNvmDataGroup1_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( RegionNvmDataGroup1_t ); + + // Region group 2 + if( NvmmCrc32Check( sizeof( RegionNvmDataGroup2_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( RegionNvmDataGroup2_t ); + + // Class b + if( NvmmCrc32Check( sizeof( LoRaMacClassBNvmData_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacClassBNvmData_t ); + + if( NvmmRead( ( uint8_t* ) nvm, sizeof( LoRaMacNvmData_t ), 0 ) == + sizeof( LoRaMacNvmData_t ) ) + { + return sizeof( LoRaMacNvmData_t ); + } +#endif + return 0; +} + +bool NvmDataMgmtFactoryReset( void ) +{ +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) + uint16_t offset = 0; + // Crypto + if( NvmmReset( sizeof( LoRaMacCryptoNvmData_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacCryptoNvmData_t ); + + // Mac Group 1 + if( NvmmReset( sizeof( LoRaMacNvmDataGroup1_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacNvmDataGroup1_t ); + + // Mac Group 2 + if( NvmmReset( sizeof( LoRaMacNvmDataGroup2_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacNvmDataGroup2_t ); + + // Secure element + if( NvmmReset( sizeof( SecureElementNvmData_t ), offset ) == false ) + { + return false; + } + offset += sizeof( SecureElementNvmData_t ); + + // Region group 1 + if( NvmmReset( sizeof( RegionNvmDataGroup1_t ), offset ) == false ) + { + return false; + } + offset += sizeof( RegionNvmDataGroup1_t ); + + // Region group 2 + if( NvmmReset( sizeof( RegionNvmDataGroup2_t ), offset ) == false ) + { + return false; + } + offset += sizeof( RegionNvmDataGroup2_t ); + + // Class b + if( NvmmReset( sizeof( LoRaMacClassBNvmData_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacClassBNvmData_t ); +#endif + return true; +} diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmDataMgmt.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmDataMgmt.h new file mode 100644 index 00000000..608af63e --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/NvmDataMgmt.h @@ -0,0 +1,71 @@ +/*! + * \file NvmDataMgmt.h + * + * \brief NVM context management implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \author Johannes Bruder ( STACKFORCE ) + * + * \defgroup NVMDATAMGMT NVM context management implementation + * This module implements the NVM context handling + * \{ + */ +#ifndef __NVMDATAMGMT_H__ +#define __NVMDATAMGMT_H__ + +/*! + * \brief NVM Management event. + * + * \param [IN] notifyFlags Bitmap which contains the information about modules that + * changed. + */ +void NvmDataMgmtEvent( uint16_t notifyFlags ); + +/*! + * \brief Function which stores the MAC data into NVM, if required. + * + * \retval Number of bytes which were stored. + */ +uint16_t NvmDataMgmtStore( void ); + +/*! + * \brief Function which restores the MAC data from NVM, if required. + * + * \retval Number of bytes which were restored. + */ +uint16_t NvmDataMgmtRestore(void ); + +/*! + * \brief Resets the NVM data. + * + * \retval Returns true, if successful. + */ +bool NvmDataMgmtFactoryReset( void ); + +/* \} */ + +#endif // __NVMDATAMGMT_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.c index 7a2f0dfe..fbbbd7f3 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.c +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.c @@ -30,600 +30,638 @@ * @brief Fragmentation Decoder definition ****************************************************************************** */ -/* Includes ------------------------------------------------------------------*/ +#include #include -#include "mw_log_conf.h" /* needed for MW_LOG */ +#include "utilities.h" #include "FragDecoder.h" -#include "sfu_fwimg_regions.h" +#include "LmhpFragmentation.h" /* LmhpFragmentationGetPackageVersion */ +#include "frag_decoder_if.h" + +/* + *============================================================================= + * Fragmentation decoder algorithm utilities + *============================================================================= + */ -/* Private typedef -----------------------------------------------------------*/ typedef struct { - FragDecoderCallbacks_t *Callbacks; - uint16_t FragNb; - uint8_t FragSize; + FragDecoderCallbacks_t *Callbacks; + uint16_t FragNb; + uint8_t FragSize; - uint32_t M2BLine; - uint8_t MatrixM2B[((FRAG_MAX_REDUNDANCY >> 3) + 1) * FRAG_MAX_REDUNDANCY]; - uint16_t FragNbMissingIndex[FRAG_MAX_NB]; + uint32_t M2BLine; + uint8_t MatrixM2B[( ( FRAG_MAX_REDUNDANCY >> 3 ) + 1 ) * FRAG_MAX_REDUNDANCY]; + uint16_t FragNbMissingIndex[FRAG_MAX_NB]; - uint8_t S[(FRAG_MAX_REDUNDANCY >> 3) + 1]; + uint8_t S[( FRAG_MAX_REDUNDANCY >> 3 ) + 1]; - FragDecoderStatus_t Status; -} FragDecoder_t; + FragDecoderStatus_t Status; +}FragDecoder_t; -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ /*! * \brief Sets a row from source into file destination * - * \param [in] src Source buffer pointer - * \param [in] row Destination index of the row to be copied - * \param [in] size Source number of bytes to be copied + * \param [IN] src Source buffer pointer + * \param [IN] row Destination index of the row to be copied + * \param [IN] size Source number of bytes to be copied */ -static void SetRow(uint8_t *src, uint16_t row, uint16_t size); +static void SetRow( uint8_t *src, uint16_t row, uint16_t size ); /*! * \brief Gets a row from source and stores it into file destination * - * \param [in] src Source buffer pointer - * \param [in] row Source index of the row to be copied - * \param [in] size Source number of bytes to be copied + * \param [IN] src Source buffer pointer + * \param [IN] row Source index of the row to be copied + * \param [IN] size Source number of bytes to be copied */ -static void GetRow(uint8_t *src, uint16_t row, uint16_t size); - +static void GetRow( uint8_t *src, uint16_t row, uint16_t size ); /*! * \brief Gets the parity value from a given row of the parity matrix * - * \param [in] index The index of the row to be computed - * \param [in] matrixRow Pointer to the parity matrix (parity bit array) + * \param [IN] index The index of the row to be computed + * \param [IN] matrixRow Pointer to the parity matrix (parity bit array) * * \retval parity Parity value at the given index */ -static uint8_t GetParity(uint16_t index, uint8_t *matrixRow); +static uint8_t GetParity( uint16_t index, uint8_t *matrixRow ); /*! * \brief Sets the parity value on the given row of the parity matrix * - * \param [in] index The index of the row to be computed + * \param [IN] index The index of the row to be computed * \param [IN/OUT] matrixRow Pointer to the parity matrix. - * \param [in] parity The parity value to be set in the parity matrix + * \param [IN] parity The parity value to be set in the parity matrix */ -static void SetParity(uint16_t index, uint8_t *matrixRow, uint8_t parity); +static void SetParity( uint16_t index, uint8_t *matrixRow, uint8_t parity ); /*! * \brief Check if the provided value is a power of 2 * - * \param [in] x Value to be tested + * \param [IN] x Value to be tested * * \retval status Return true if frame is a power of two */ -static bool IsPowerOfTwo(uint32_t x); +static bool IsPowerOfTwo( uint32_t x ); /*! * \brief XOrs two data lines * - * \param [in] line1 1st Data line to be XORed - * \param [in] line2 2nd Data line to be XORed - * \param [in] size Number of elements in line1 + * \param [IN] line1 1st Data line to be XORed + * \param [IN] line2 2nd Data line to be XORed + * \param [IN] size Number of elements in line1 * - * \param [out] result XOR( line1, line2 ) result stored in line1 + * \param [OUT] result XOR( line1, line2 ) result stored in line1 */ -static void XorDataLine(uint8_t *line1, uint8_t *line2, int32_t size); +static void XorDataLine( uint8_t *line1, uint8_t *line2, int32_t size ); /*! * \brief XORs two parity lines * - * \param [in] line1 1st Parity line to be XORed - * \param [in] line2 2nd Parity line to be XORed - * \param [in] size Number of elements in line1 + * \param [IN] line1 1st Parity line to be XORed + * \param [IN] line2 2nd Parity line to be XORed + * \param [IN] size Number of elements in line1 * - * \param [out] result XOR( line1, line2 ) result stored in line1 + * \param [OUT] result XOR( line1, line2 ) result stored in line1 */ -static void XorParityLine(uint8_t *line1, uint8_t *line2, int32_t size); +static void XorParityLine( uint8_t* line1, uint8_t* line2, int32_t size ); /*! * \brief Generates a pseudo random number : PRBS23 * - * \param [in] value The input of the PRBS23 generator + * \param [IN] value The input of the PRBS23 generator * * \retval nextValue Returns the next pseudo random number */ -static int32_t FragPrbs23(int32_t value); +static int32_t FragPrbs23( int32_t value ); /*! * \brief Gets and fills the parity matrix * - * \param [in] n Fragment N - * \param [in] m Fragment number - * \param [out] matrixRow Parity matrix + * \param [IN] n Fragment N + * \param [IN] m Fragment number + * \param [OUT] matrixRow Parity matrix */ -static void FragGetParityMatrixRow(int32_t n, int32_t m, uint8_t *matrixRow); +static void FragGetParityMatrixRow( int32_t n, int32_t m, uint8_t *matrixRow ); /*! * \brief Finds the index of the first one in a bit array * - * \param [in] bitArray Pointer to the bit array - * \param [in] size Bit array size + * \param [IN] bitArray Pointer to the bit array + * \param [IN] size Bit array size * \retval index The index of the first 1 in the bit array */ -static uint16_t BitArrayFindFirstOne(uint8_t *bitArray, uint16_t size); +static uint16_t BitArrayFindFirstOne( uint8_t *bitArray, uint16_t size ); /*! * \brief Checks if the provided bit array only contains zeros * - * \param [in] bitArray Pointer to the bit array - * \param [in] size Bit array size + * \param [IN] bitArray Pointer to the bit array + * \param [IN] size Bit array size * \retval isAllZeros [0: Contains ones, 1: Contains all zeros] */ -static uint8_t BitArrayIsAllZeros(uint8_t *bitArray, uint16_t size); +static uint8_t BitArrayIsAllZeros( uint8_t *bitArray, uint16_t size ); /*! * \brief Finds & marks missing fragments * - * \param [in] counter Current fragment counter - * \param [out] FragDecoder.FragNbMissingIndex[] array is updated in place + * \param [IN] counter Current fragment counter + * \param [OUT] FragDecoder.FragNbMissingIndex[] array is updated in place */ -static void FragFindMissingFrags(uint16_t counter); +static void FragFindMissingFrags( uint16_t counter ); /*! * \brief Finds the index (frag counter) of the x th missing frag * - * \param [in] x x th missing frag + * \param [IN] x x th missing frag * * \retval counter The counter value associated to the x th missing frag */ -static uint16_t FragFindMissingIndex(uint16_t x); +static uint16_t FragFindMissingIndex( uint16_t x ); /*! * \brief Extacts a row from the binary matrix and expands it to a bitArray * - * \param [in] bitArray Pointer to the bit array - * \param [in] rowIndex Matrix row index - * \param [in] bitsInRow Number of bits in one row + * \param [IN] bitArray Pointer to the bit array + * \param [IN] rowIndex Matrix row index + * \param [IN] bitsInRow Number of bits in one row */ -static void FragExtractLineFromBinaryMatrix(uint8_t *bitArray, uint16_t rowIndex, uint16_t bitsInRow); +static void FragExtractLineFromBinaryMatrix( uint8_t* bitArray, uint16_t rowIndex, uint16_t bitsInRow ); /*! * \brief Collapses and Pushs a row of a bit array to the matrix * - * \param [in] bitArray Pointer to the bit array - * \param [in] rowIndex Matrix row index - * \param [in] bitsInRow Number of bits in one row + * \param [IN] bitArray Pointer to the bit array + * \param [IN] rowIndex Matrix row index + * \param [IN] bitsInRow Number of bits in one row + */ +static void FragPushLineToBinaryMatrix( uint8_t *bitArray, uint16_t rowIndex, uint16_t bitsInRow ); + +/* + *============================================================================= + * Fragmentation decoder algorithm + *============================================================================= */ -static void FragPushLineToBinaryMatrix(uint8_t *bitArray, uint16_t rowIndex, uint16_t bitsInRow); -/* Private variables ---------------------------------------------------------*/ static FragDecoder_t FragDecoder; -/* Exported functions ---------------------------------------------------------*/ -void FragDecoderInit(uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t *callbacks) +void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t *callbacks ) { -#if (INTEROP_TEST_MODE == 1) - uint8_t init_buffer[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; -#endif /* INTEROP_TEST_MODE == 1 */ - FragDecoder.Callbacks = callbacks; - FragDecoder.FragNb = fragNb; /* FragNb = FRAG_MAX_SIZE */ - FragDecoder.FragSize = fragSize; /* number of byte on a row */ - FragDecoder.Status.FragNbLastRx = 0; - FragDecoder.Status.FragNbLost = 0; - FragDecoder.M2BLine = 0; - - - /* Initialize missing fragments index array */ - for (uint16_t i = 0; i < FRAG_MAX_NB; i++) - { - FragDecoder.FragNbMissingIndex[i] = 1; - } - - /* Initialize parity matrix */ - for (uint32_t i = 0; i < ((FRAG_MAX_REDUNDANCY >> 3) + 1); i++) - { - FragDecoder.S[i] = 0; - } - - for (uint32_t i = 0; i < (((FRAG_MAX_REDUNDANCY >> 3) + 1) * FRAG_MAX_REDUNDANCY); i++) - { - FragDecoder.MatrixM2B[i] = 0xFF; - } - - /* Initialize final uncoded data buffer ( FRAG_MAX_NB * FRAG_MAX_SIZE ) */ -#if (INTEROP_TEST_MODE == 1) - FragDecoder.Callbacks->FragDecoderErase(0, fragNb * fragSize); -#else /* INTEROP_TEST_MODE == 0 */ - FragDecoder.Callbacks->FragDecoderErase(0, SlotEndAdd[SLOT_DWL_1] - SlotStartAdd[SLOT_DWL_1] + 1U); -#endif /* INTEROP_TEST_MODE */ - - FragDecoder.Status.FragNbLost = 0; - FragDecoder.Status.FragNbLastRx = 0; + FragDecoder.Callbacks = callbacks; + FragDecoder.FragNb = fragNb; // FragNb = FRAG_MAX_SIZE + FragDecoder.FragSize = fragSize; // number of byte on a row + FragDecoder.Status.FragNbLastRx = 0; + FragDecoder.Status.FragNbLost = 0; + FragDecoder.M2BLine = 0; + + // Initialize missing fragments index array + for( uint16_t i = 0; i < FRAG_MAX_NB; i++ ) + { + FragDecoder.FragNbMissingIndex[i] = 1; + } + + // Initialize parity matrix + for( uint32_t i = 0; i < ( ( FRAG_MAX_REDUNDANCY >> 3 ) + 1 ); i++ ) + { + FragDecoder.S[i] = 0; + } + + for( uint32_t i = 0; i < ( ( ( FRAG_MAX_REDUNDANCY >> 3 ) + 1 ) * FRAG_MAX_REDUNDANCY ); i++ ) + { + FragDecoder.MatrixM2B[i] = 0xFF; + } + + // Initialize final uncoded data buffer ( FRAG_MAX_NB * FRAG_MAX_SIZE ) + if (FragDecoder.Callbacks->FragDecoderErase != NULL) + { + FragDecoder.Callbacks->FragDecoderErase(); + } + + FragDecoder.Status.FragNbLost = 0; + FragDecoder.Status.FragNbLastRx = 0; } -uint32_t FragDecoderGetMaxFileSize(void) +uint32_t FragDecoderGetMaxFileSize( void ) { - return FRAG_MAX_NB * FRAG_MAX_SIZE; + return FRAG_MAX_NB * FRAG_MAX_SIZE; } -int32_t FragDecoderProcess(uint16_t fragCounter, uint8_t *rawData) +int32_t FragDecoderProcess( uint16_t fragCounter, uint8_t *rawData ) { - uint16_t firstOneInRow = 0; - int32_t first = 0; - int32_t noInfo = 0; - - uint8_t matrixRow[(FRAG_MAX_NB >> 3) + 1]; - uint8_t matrixDataTemp[FRAG_MAX_SIZE]; - uint8_t dataTempVector[(FRAG_MAX_REDUNDANCY >> 3) + 1]; - uint8_t dataTempVector2[(FRAG_MAX_REDUNDANCY >> 3) + 1]; - - UTIL_MEM_set_8(matrixRow, 0, (FRAG_MAX_NB >> 3) + 1); - UTIL_MEM_set_8(matrixDataTemp, 0, FRAG_MAX_SIZE); - UTIL_MEM_set_8(dataTempVector, 0, (FRAG_MAX_REDUNDANCY >> 3) + 1); - UTIL_MEM_set_8(dataTempVector2, 0, (FRAG_MAX_REDUNDANCY >> 3) + 1); - - FragDecoder.Status.FragNbRx = fragCounter; - - if (fragCounter < FragDecoder.Status.FragNbLastRx) - { - return FRAG_SESSION_ONGOING; /* Drop frame out of order */ - } - - /* The M (FragNb) first packets aren't encoded or in other words they are */ - /* encoded with the unitary matrix */ - if (fragCounter < (FragDecoder.FragNb + 1)) - { - /* The M first frame are not encoded store them */ - SetRow(rawData, fragCounter - 1, FragDecoder.FragSize); - - FragDecoder.FragNbMissingIndex[fragCounter - 1] = 0; - - /* Update the FragDecoder.FragNbMissingIndex with the losing frame */ - FragFindMissingFrags(fragCounter); - } - else - { - if (FragDecoder.Status.FragNbLost > FRAG_MAX_REDUNDANCY) - { - FragDecoder.Status.MatrixError = 1; - return FRAG_SESSION_FINISHED; - } - /* At this point we receive encoded frames and the number of losing frames */ - /* is well known: FragDecoder.FragNbLost - 1; */ + uint16_t firstOneInRow = 0; + int32_t first = 0; + int32_t noInfo = 0; + + uint8_t matrixRow[(FRAG_MAX_NB >> 3 ) + 1]; + uint8_t matrixDataTemp[FRAG_MAX_SIZE]; + uint8_t dataTempVector[( FRAG_MAX_REDUNDANCY >> 3 ) + 1]; + uint8_t dataTempVector2[( FRAG_MAX_REDUNDANCY >> 3 ) + 1]; - /* In case of the end of true data is missing */ - FragFindMissingFrags(fragCounter); + UTIL_MEM_set_8(matrixRow, 0, (FRAG_MAX_NB >> 3) + 1); + UTIL_MEM_set_8(matrixDataTemp, 0, FRAG_MAX_SIZE); + UTIL_MEM_set_8(dataTempVector, 0, (FRAG_MAX_REDUNDANCY >> 3) + 1); + UTIL_MEM_set_8(dataTempVector2, 0, (FRAG_MAX_REDUNDANCY >> 3) + 1); - if (FragDecoder.Status.FragNbLost == 0) + FragDecoder.Status.FragNbRx = fragCounter; + + if( fragCounter < FragDecoder.Status.FragNbLastRx ) { - /* the case : all the M(FragNb) first rows have been transmitted with no error */ - return FragDecoder.Status.FragNbLost; + return FRAG_SESSION_ONGOING; // Drop frame out of order } - /* fragCounter - FragDecoder.FragNb */ - FragGetParityMatrixRow(fragCounter - FragDecoder.FragNb, FragDecoder.FragNb, matrixRow); - - for (int32_t i = 0; i < FragDecoder.FragNb; i++) + // The M (FragNb) first packets aren't encoded or in other words they are + // encoded with the unitary matrix + if( fragCounter < ( FragDecoder.FragNb + 1 ) ) { - if (GetParity(i, matrixRow) == 1) - { - if (FragDecoder.FragNbMissingIndex[i] == 0) + // The M first frame are not encoded store them + SetRow( rawData, fragCounter - 1, FragDecoder.FragSize ); + + FragDecoder.FragNbMissingIndex[fragCounter - 1] = 0; + + // Update the FragDecoder.FragNbMissingIndex with the loosing frame + FragFindMissingFrags( fragCounter ); + + if ((fragCounter == FragDecoder.FragNb) && (FragDecoder.Status.FragNbLost == 0U)) { - /* XOR with already receive frag */ - SetParity(i, matrixRow, 0); - GetRow(matrixDataTemp, i, FragDecoder.FragSize); - XorDataLine(rawData, matrixDataTemp, FragDecoder.FragSize); + return FRAG_SESSION_FINISHED; } - else + } + else + { + if( FragDecoder.Status.FragNbLost > FRAG_MAX_REDUNDANCY ) { - /* Fill the "little" boolean matrix m2b */ - SetParity(FragDecoder.FragNbMissingIndex[i] - 1, dataTempVector, 1); - if (first == 0) - { - first = 1; - } + FragDecoder.Status.MatrixError = 1; + return FRAG_SESSION_FINISHED; } - } - } + // At this point we receive encoded frames and the number of loosing frames + // is well known: FragDecoder.FragNbLost - 1; - firstOneInRow = BitArrayFindFirstOne(dataTempVector, FragDecoder.Status.FragNbLost); + // In case of the end of true data is missing + FragFindMissingFrags( fragCounter ); - if (first > 0) - { - int32_t li; - int32_t lj; - - /* Manage a new line in MatrixM2B */ - while (GetParity(firstOneInRow, FragDecoder.S) == 1) - { - /* Row already diagonalized exist & ( FragDecoder.MatrixM2B[firstOneInRow][0] ) */ - FragExtractLineFromBinaryMatrix(dataTempVector2, firstOneInRow, FragDecoder.Status.FragNbLost); - XorParityLine(dataTempVector, dataTempVector2, FragDecoder.Status.FragNbLost); - /* Have to store it in the mi th position of the missing frag */ - li = FragFindMissingIndex(firstOneInRow); - GetRow(matrixDataTemp, li, FragDecoder.FragSize); - XorDataLine(rawData, matrixDataTemp, FragDecoder.FragSize); - if (BitArrayIsAllZeros(dataTempVector, FragDecoder.Status.FragNbLost)) - { - noInfo = 1; - break; + if( FragDecoder.Status.FragNbLost == 0 ) + { + // the case : all the M(FragNb) first rows have been transmitted with no error + return FragDecoder.Status.FragNbLost; } - firstOneInRow = BitArrayFindFirstOne(dataTempVector, FragDecoder.Status.FragNbLost); - } - - if (noInfo == 0) - { - FragPushLineToBinaryMatrix(dataTempVector, firstOneInRow, FragDecoder.Status.FragNbLost); - li = FragFindMissingIndex(firstOneInRow); - SetRow(rawData, li, FragDecoder.FragSize); - SetParity(firstOneInRow, FragDecoder.S, 1); - FragDecoder.M2BLine++; - } - - if (FragDecoder.M2BLine == FragDecoder.Status.FragNbLost) - { - /* Then last step diagonalized */ - if (FragDecoder.Status.FragNbLost > 1) - { - int32_t i; - int32_t j; - - for (i = (FragDecoder.Status.FragNbLost - 2); i >= 0 ; i--) - { - li = FragFindMissingIndex(i); - GetRow(matrixDataTemp, li, FragDecoder.FragSize); - for (j = (FragDecoder.Status.FragNbLost - 1); j > i; j--) - { - FragExtractLineFromBinaryMatrix(dataTempVector2, i, FragDecoder.Status.FragNbLost); - FragExtractLineFromBinaryMatrix(dataTempVector, j, FragDecoder.Status.FragNbLost); - if (GetParity(j, dataTempVector2) == 1) - { - XorParityLine(dataTempVector2, dataTempVector, FragDecoder.Status.FragNbLost); - lj = FragFindMissingIndex(j); + // fragCounter - FragDecoder.FragNb + FragGetParityMatrixRow( fragCounter - FragDecoder.FragNb, FragDecoder.FragNb, matrixRow ); - GetRow(rawData, lj, FragDecoder.FragSize); - XorDataLine(matrixDataTemp, rawData, FragDecoder.FragSize); - } + for( int32_t i = 0; i < FragDecoder.FragNb; i++ ) + { + if( GetParity( i , matrixRow ) == 1 ) + { + if( FragDecoder.FragNbMissingIndex[i] == 0 ) + { + // XOR with already receive frag + SetParity( i, matrixRow, 0 ); + GetRow( matrixDataTemp, i, FragDecoder.FragSize ); + XorDataLine( rawData, matrixDataTemp, FragDecoder.FragSize ); + } + else + { + // Fill the "little" boolean matrix m2b + SetParity( FragDecoder.FragNbMissingIndex[i] - 1, dataTempVector, 1 ); + if( first == 0 ) + { + first = 1; + } + } } - SetRow(matrixDataTemp, li, FragDecoder.FragSize); - } - return FragDecoder.Status.FragNbLost; } - else + + firstOneInRow = BitArrayFindFirstOne( dataTempVector, FragDecoder.Status.FragNbLost ); + + if( first > 0 ) { - /* If not ( FragDecoder.FragNbLost > 1 ) */ - return FragDecoder.Status.FragNbLost; + int32_t li; + int32_t lj; + + // Manage a new line in MatrixM2B + while( GetParity( firstOneInRow, FragDecoder.S ) == 1 ) + { + // Row already diagonalized exist & ( FragDecoder.MatrixM2B[firstOneInRow][0] ) + FragExtractLineFromBinaryMatrix( dataTempVector2, firstOneInRow, FragDecoder.Status.FragNbLost ); + XorParityLine( dataTempVector, dataTempVector2, FragDecoder.Status.FragNbLost ); + // Have to store it in the mi th position of the missing frag + li = FragFindMissingIndex( firstOneInRow ); + GetRow( matrixDataTemp, li, FragDecoder.FragSize ); + XorDataLine( rawData, matrixDataTemp, FragDecoder.FragSize ); + if( BitArrayIsAllZeros( dataTempVector, FragDecoder.Status.FragNbLost ) ) + { + noInfo = 1; + break; + } + firstOneInRow = BitArrayFindFirstOne( dataTempVector, FragDecoder.Status.FragNbLost ); + } + + if( noInfo == 0 ) + { + FragPushLineToBinaryMatrix( dataTempVector, firstOneInRow, FragDecoder.Status.FragNbLost ); + li = FragFindMissingIndex( firstOneInRow ); + SetRow( rawData, li, FragDecoder.FragSize ); + SetParity( firstOneInRow, FragDecoder.S, 1 ); + FragDecoder.M2BLine++; + } + + if( FragDecoder.M2BLine == FragDecoder.Status.FragNbLost ) + { + // Then last step diagonalized + if( FragDecoder.Status.FragNbLost > 1 ) + { + int32_t i; + int32_t j; + + for( i = ( FragDecoder.Status.FragNbLost - 2 ); i >= 0 ; i-- ) + { + li = FragFindMissingIndex( i ); + GetRow( matrixDataTemp, li, FragDecoder.FragSize ); + for( j = ( FragDecoder.Status.FragNbLost - 1 ); j > i; j--) + { + FragExtractLineFromBinaryMatrix( dataTempVector2, i, FragDecoder.Status.FragNbLost ); + FragExtractLineFromBinaryMatrix( dataTempVector, j, FragDecoder.Status.FragNbLost ); + if( GetParity( j, dataTempVector2 ) == 1 ) + { + XorParityLine( dataTempVector2, dataTempVector, FragDecoder.Status.FragNbLost ); + + lj = FragFindMissingIndex( j ); + + GetRow( rawData, lj, FragDecoder.FragSize ); + XorDataLine( matrixDataTemp , rawData , FragDecoder.FragSize ); + } + } + SetRow( matrixDataTemp, li, FragDecoder.FragSize ); + } + return FragDecoder.Status.FragNbLost; + } + else + { + //If not ( FragDecoder.FragNbLost > 1 ) + return FragDecoder.Status.FragNbLost; + } + } } - } } - } - return FRAG_SESSION_ONGOING; + return FRAG_SESSION_ONGOING; } -FragDecoderStatus_t FragDecoderGetStatus(void) -{ - return FragDecoder.Status; +FragDecoderStatus_t FragDecoderGetStatus( void ) +{ + return FragDecoder.Status; } -/* Private functions ---------------------------------------------------------*/ -static void SetRow(uint8_t *src, uint16_t row, uint16_t size) +/* + *============================================================================= + * Fragmentation decoder algorithm utilities + *============================================================================= + */ + +static void SetRow( uint8_t *src, uint16_t row, uint16_t size ) { - if ((FragDecoder.Callbacks != NULL) && (FragDecoder.Callbacks->FragDecoderWrite != NULL)) - { - FragDecoder.Callbacks->FragDecoderWrite(row * size, src, size); - } + if( ( FragDecoder.Callbacks != NULL ) && ( FragDecoder.Callbacks->FragDecoderWrite != NULL ) ) + { + FragDecoder.Callbacks->FragDecoderWrite( row * size, src, size ); + } } -static void GetRow(uint8_t *dst, uint16_t row, uint16_t size) +static void GetRow( uint8_t *dst, uint16_t row, uint16_t size ) { - if ((FragDecoder.Callbacks != NULL) && (FragDecoder.Callbacks->FragDecoderRead != NULL)) - { - FragDecoder.Callbacks->FragDecoderRead(row * size, dst, size); - } + if( ( FragDecoder.Callbacks != NULL ) && ( FragDecoder.Callbacks->FragDecoderRead != NULL ) ) + { + FragDecoder.Callbacks->FragDecoderRead( row * size, dst, size ); + } } -static uint8_t GetParity(uint16_t index, uint8_t *matrixRow) +static uint8_t GetParity( uint16_t index, uint8_t *matrixRow ) { - uint8_t parity; - parity = matrixRow[index >> 3]; - parity = (parity >> (7 - (index % 8))) & 0x01; - return parity; + uint8_t parity; + parity = matrixRow[index >> 3]; + parity = ( parity >> ( 7 - ( index % 8 ) ) ) & 0x01; + return parity; } -static void SetParity(uint16_t index, uint8_t *matrixRow, uint8_t parity) +static void SetParity( uint16_t index, uint8_t *matrixRow, uint8_t parity ) { - uint8_t mask = 0xFF - (1 << (7 - (index % 8))); - parity = parity << (7 - (index % 8)); - matrixRow[index >> 3] = (matrixRow[index >> 3] & mask) + parity; + uint8_t mask = 0xFF - ( 1 << ( 7 - ( index % 8 ) ) ); + parity = parity << ( 7 - ( index % 8 ) ); + matrixRow[index >> 3] = ( matrixRow[index >> 3] & mask ) + parity; } -static bool IsPowerOfTwo(uint32_t x) +static bool IsPowerOfTwo( uint32_t x ) { - uint8_t sumBit = 0; - - for (uint8_t i = 0; i < 32; i++) - { - sumBit += (x & (1 << i)) >> i; - } - if (sumBit == 1) - { - return true; - } - return false; + uint8_t sumBit = 0; + + for( uint8_t i = 0; i < 32; i++ ) + { + sumBit += ( x & ( 1 << i ) ) >> i; + } + if( sumBit == 1 ) + { + return true; + } + return false; } -static void XorDataLine(uint8_t *line1, uint8_t *line2, int32_t size) +static void XorDataLine( uint8_t *line1, uint8_t *line2, int32_t size ) { - for (int32_t i = 0; i < size; i++) - { - line1[i] = line1[i] ^ line2[i]; - } + for( int32_t i = 0; i < size; i++ ) + { + line1[i] = line1[i] ^ line2[i]; + } } -static void XorParityLine(uint8_t *line1, uint8_t *line2, int32_t size) +static void XorParityLine( uint8_t* line1, uint8_t* line2, int32_t size ) { - for (int32_t i = 0; i < size; i++) - { - SetParity(i, line1, (GetParity(i, line1) ^ GetParity(i, line2))); - } + for( int32_t i = 0; i < size; i++ ) + { + SetParity( i, line1, ( GetParity( i, line1 ) ^ GetParity( i, line2 ) ) ); + } } -static int32_t FragPrbs23(int32_t value) +static int32_t FragPrbs23( int32_t value ) { - int32_t b0 = value & 0x01; - int32_t b1 = (value & 0x20) >> 5; - return (value >> 1) + ((b0 ^ b1) << 22);; + int32_t b0 = value & 0x01; + int32_t b1 = ( value & 0x20 ) >> 5; + return ( value >> 1 ) + ( ( b0 ^ b1 ) << 22 ); } -static void FragGetParityMatrixRow(int32_t n, int32_t m, uint8_t *matrixRow) +static void FragGetParityMatrixRow( int32_t n, int32_t m, uint8_t *matrixRow ) { - int32_t mTemp; - int32_t x; - int32_t nbCoeff = 0; - int32_t r; - - if (IsPowerOfTwo(m) != false) - { - mTemp = 1; - } - else - { - mTemp = 0; - } - - x = 1 + (1001 * n); - for (uint8_t i = 0; i < ((m >> 3) + 1); i++) - { - matrixRow[i] = 0; - } - while (nbCoeff < (m >> 1)) - { - r = 1 << 16; - while (r >= m) + int32_t mTemp; + int32_t x; + int32_t nbCoeff = 0; + int32_t r; + + if( IsPowerOfTwo( m ) != false ) { - x = FragPrbs23(x); - r = x % (m + mTemp); + mTemp = 1; + } + else + { + mTemp = 0; + } + + x = 1 + ( 1001 * n ); + for( uint8_t i = 0; i < ( ( m >> 3 ) + 1 ); i++ ) + { + matrixRow[i] = 0; + } + while( nbCoeff < ( m >> 1 ) ) + { + r = 1 << 16; + while( r >= m ) + { + x = FragPrbs23( x ); + r = x % ( m + mTemp ); + } + + // FEC algorithm optimization in V2.0.0 + if ((GetParity(r, matrixRow) == 0) || (LmhpFragmentationGetPackageVersion() == 1U)) + { + SetParity(r, matrixRow, 1); + nbCoeff += 1; + } } - SetParity(r, matrixRow, 1); - nbCoeff += 1; - } } -static uint16_t BitArrayFindFirstOne(uint8_t *bitArray, uint16_t size) +static uint16_t BitArrayFindFirstOne( uint8_t *bitArray, uint16_t size ) { - for (uint16_t i = 0; i < size; i++) - { - if (GetParity(i, bitArray) == 1) + for( uint16_t i = 0; i < size; i++) { - return i; + if ( GetParity( i, bitArray ) == 1 ) + { + return i; + } } - } - return 0; + return 0; } -static uint8_t BitArrayIsAllZeros(uint8_t *bitArray, uint16_t size) +static uint8_t BitArrayIsAllZeros( uint8_t *bitArray, uint16_t size ) { - for (uint16_t i = 0; i < size; i++) - { - if (GetParity(i, bitArray) == 1) + for( uint16_t i = 0; i < size; i++ ) { - return 0; + if( GetParity( i, bitArray ) == 1 ) + { + return 0; + } } - } - return 1; + return 1; } -static void FragFindMissingFrags(uint16_t counter) +/*! + * \brief Finds & marks missing fragments + * + * \param [IN] counter Current fragment counter + * \param [OUT] FragDecoder.FragNbMissingIndex[] array is updated in place + */ +static void FragFindMissingFrags( uint16_t counter ) { - int32_t i; - for (i = FragDecoder.Status.FragNbLastRx; i < (counter - 1); i++) - { - if (i < FragDecoder.FragNb) + int32_t i; + for( i = FragDecoder.Status.FragNbLastRx; i < ( counter - 1 ); i++ ) + { + if( i < FragDecoder.FragNb ) + { + FragDecoder.Status.FragNbLost++; + FragDecoder.FragNbMissingIndex[i] = FragDecoder.Status.FragNbLost; + } + } + if( i < FragDecoder.FragNb ) + { + FragDecoder.Status.FragNbLastRx = counter; + } + else { - FragDecoder.Status.FragNbLost++; - FragDecoder.FragNbMissingIndex[i] = FragDecoder.Status.FragNbLost; + FragDecoder.Status.FragNbLastRx = FragDecoder.FragNb + 1; } - } - if (i < FragDecoder.FragNb) - { - FragDecoder.Status.FragNbLastRx = counter; - } - else - { - FragDecoder.Status.FragNbLastRx = FragDecoder.FragNb + 1; - } - MW_LOG(TS_ON, VLEVEL_H, "RECEIVED : %5d / %5d Fragments\r\n", FragDecoder.Status.FragNbRx, FragDecoder.FragNb); - MW_LOG(TS_ON, VLEVEL_H, " %5d / %5d Bytes\r\n", FragDecoder.Status.FragNbRx * FragDecoder.FragSize, - FragDecoder.FragNb * FragDecoder.FragSize); - MW_LOG(TS_ON, VLEVEL_H, "LOST : %7d Fragments\r\n\r\n", FragDecoder.Status.FragNbLost); } -static uint16_t FragFindMissingIndex(uint16_t x) +/*! + * \brief Finds the index (frag counter) of the x th missing frag + * + * \param [IN] x x th missing frag + * + * \retval counter The counter value associated to the x th missing frag + */ +static uint16_t FragFindMissingIndex( uint16_t x ) { - for (uint16_t i = 0; i < FragDecoder.FragNb; i++) - { - if (FragDecoder.FragNbMissingIndex[i] == (x + 1)) + for( uint16_t i = 0; i < FragDecoder.FragNb; i++ ) { - return i; + if( FragDecoder.FragNbMissingIndex[i] == ( x + 1 ) ) + { + return i; + } } - } - return 0; + return 0; } -static void FragExtractLineFromBinaryMatrix(uint8_t *bitArray, uint16_t rowIndex, uint16_t bitsInRow) +/*! + * \brief Extacts a row from the binary matrix and expands it to a bitArray + * + * \param [IN] bitArray Pointer to the bit array + * \param [IN] rowIndex Matrix row index + * \param [IN] bitsInRow Number of bits in one row + */ +static void FragExtractLineFromBinaryMatrix( uint8_t* bitArray, uint16_t rowIndex, uint16_t bitsInRow ) { - uint32_t findByte = 0; - uint32_t findBitInByte = 0; - - if (rowIndex > 0) - { - findByte = (rowIndex * bitsInRow - ((rowIndex * (rowIndex - 1)) >> 1)) >> 3; - findBitInByte = (rowIndex * bitsInRow - ((rowIndex * (rowIndex - 1)) >> 1)) % 8; - } - if (rowIndex > 0) - { - for (uint16_t i = 0; i < rowIndex; i++) + uint32_t findByte = 0; + uint32_t findBitInByte = 0; + + if( rowIndex > 0 ) { - SetParity(i, bitArray, 0); + findByte = ( rowIndex * bitsInRow - ( ( rowIndex * ( rowIndex - 1 ) ) >> 1 ) ) >> 3; + findBitInByte = ( rowIndex * bitsInRow - ( ( rowIndex * ( rowIndex - 1 ) ) >> 1 ) ) % 8; + } + if( rowIndex > 0 ) + { + for( uint16_t i = 0; i < rowIndex; i++ ) + { + SetParity( i, bitArray, 0 ); + } } - } - for (uint16_t i = rowIndex; i < bitsInRow; i++) - { - SetParity(i, - bitArray, - (FragDecoder.MatrixM2B[findByte] >> (7 - findBitInByte)) & 0x01); - - findBitInByte++; - if (findBitInByte == 8) + for( uint16_t i = rowIndex; i < bitsInRow; i++ ) { - findBitInByte = 0; - findByte++; + SetParity( i, + bitArray, + ( FragDecoder.MatrixM2B[findByte] >> ( 7 - findBitInByte ) ) & 0x01 ); + + findBitInByte++; + if( findBitInByte == 8 ) + { + findBitInByte = 0; + findByte++; + } } - } } -static void FragPushLineToBinaryMatrix(uint8_t *bitArray, uint16_t rowIndex, uint16_t bitsInRow) +/*! + * \brief Collapses and Pushs a row of a bit array to the matrix + * + * \param [IN] bitArray Pointer to the bit array + * \param [IN] rowIndex Matrix row index + * \param [IN] bitsInRow Number of bits in one row + */ +static void FragPushLineToBinaryMatrix( uint8_t *bitArray, uint16_t rowIndex, uint16_t bitsInRow ) { - uint32_t findByte = 0; - uint32_t findBitInByte = 0; - - if (rowIndex > 0) - { - findByte = (rowIndex * bitsInRow - ((rowIndex * (rowIndex - 1)) >> 1)) >> 3; - findBitInByte = (rowIndex * bitsInRow - ((rowIndex * (rowIndex - 1)) >> 1)) % 8; - - } - for (uint16_t i = rowIndex; i < bitsInRow; i++) - { - if (GetParity(i, bitArray) == 0) - { - FragDecoder.MatrixM2B[findByte] = FragDecoder.MatrixM2B[findByte] & (0xFF - (1 << (7 - findBitInByte))); + uint32_t findByte = 0; + uint32_t findBitInByte = 0; + + if ( rowIndex > 0) { + findByte = ( rowIndex * bitsInRow - ( ( rowIndex * ( rowIndex - 1 ) ) >> 1 ) ) >> 3; + findBitInByte = ( rowIndex * bitsInRow - ( ( rowIndex * ( rowIndex - 1 ) ) >> 1 ) ) % 8; + } - findBitInByte++; - if (findBitInByte == 8) + for( uint16_t i = rowIndex; i < bitsInRow; i++ ) { - findBitInByte = 0; - findByte++; + if( GetParity( i, bitArray ) == 0 ) + { + FragDecoder.MatrixM2B[findByte] = FragDecoder.MatrixM2B[findByte] & ( 0xFF - ( 1 << ( 7 - findBitInByte ) ) ); + } + findBitInByte++; + if( findBitInByte == 8 ) + { + findBitInByte = 0; + findByte++; + } } - } } diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.h index 21dc2d57..0a27fb33 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/FragDecoder.h @@ -33,148 +33,84 @@ #ifndef __FRAG_DECODER_H__ #define __FRAG_DECODER_H__ -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ #include -/* Exported defines ----------------------------------------------------------*/ -#define INTEROP_TEST_MODE 0 - -#if (INTEROP_TEST_MODE == 1) -/*! - * Maximum number of fragment that can be handled. - * - * \remark This parameter has an impact on the memory footprint. - */ -#define FRAG_MAX_NB 21 - -/*! - * Maximum fragment size that can be handled. - * - * \remark This parameter has an impact on the memory footprint. - */ -#define FRAG_MAX_SIZE 50 - -/*! - * Maximum number of extra frames that can be handled. - * - * \remark This parameter has an impact on the memory footprint. - */ -#define FRAG_MAX_REDUNDANCY 5 -#else /* INTEROP_TEST_MODE == 0 */ -/*! - * Maximum number of fragment that can be handled. - * - * \remark This parameter has an impact on the memory footprint. - */ -#define FRAG_MAX_NB 250 - -/*! - * Maximum fragment size that can be handled. - * - * \remark This parameter has an impact on the memory footprint. - */ -#define FRAG_MAX_SIZE 216 - -/*! - * Maximum number of extra frames that can be handled. - * - * \remark This parameter has an impact on the memory footprint. - */ -#define FRAG_MAX_REDUNDANCY 40 -#endif /* INTEROP_TEST_MODE */ - #define FRAG_SESSION_FINISHED ( int32_t )0 #define FRAG_SESSION_NOT_STARTED ( int32_t )-2 #define FRAG_SESSION_ONGOING ( int32_t )-1 -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ typedef struct sFragDecoderStatus { - uint16_t FragNbRx; - uint16_t FragNbLost; - uint16_t FragNbLastRx; - uint8_t MatrixError; -} FragDecoderStatus_t; + uint16_t FragNbRx; + uint16_t FragNbLost; + uint16_t FragNbLastRx; + uint8_t MatrixError; +}FragDecoderStatus_t; typedef struct sFragDecoderCallbacks { - /*! - * Init `data` buffer of `size` starting at address `addr` - * - * \param [in] addr Address start index to erase. - * \param [in] size number of bytes. - * - * \retval status Write operation status [0: Success, -1 Fail] - */ - uint8_t (*FragDecoderErase)(uint32_t addr, uint32_t size); - /*! - * Writes `data` buffer of `size` starting at address `addr` - * - * \param [in] addr Address start index to write to. - * \param [in] data Data buffer to be written. - * \param [in] size Size of data buffer to be written. - * - * \retval status Write operation status [0: Success, -1 Fail] - */ - uint8_t (*FragDecoderWrite)(uint32_t addr, uint8_t *data, uint32_t size); - /*! - * Reads `data` buffer of `size` starting at address `addr` - * - * \param [in] addr Address start index to read from. - * \param [in] data Data buffer to be read. - * \param [in] size Size of data buffer to be read. - * - * \retval status Read operation status [0: Success, -1 Fail] - */ - uint8_t (*FragDecoderRead)(uint32_t addr, uint8_t *data, uint32_t size); -} FragDecoderCallbacks_t; + /*! + * Initialize final uncoded data buffer + * + * \retval status Write operation status [0: Success, -1 Fail] + */ + int32_t ( *FragDecoderErase )( void ); + /*! + * Writes `data` buffer of `size` starting at address `addr` + * + * \param [IN] addr Address start index to write to. + * \param [IN] data Data buffer to be written. + * \param [IN] size Size of data buffer to be written. + * + * \retval status Write operation status [0: Success, -1 Fail] + */ + int32_t ( *FragDecoderWrite )( uint32_t addr, uint8_t *data, uint32_t size ); + /*! + * Reads `data` buffer of `size` starting at address `addr` + * + * \param [IN] addr Address start index to read from. + * \param [IN] data Data buffer to be read. + * \param [IN] size Size of data buffer to be read. + * + * \retval status Read operation status [0: Success, -1 Fail] + */ + int32_t ( *FragDecoderRead )( uint32_t addr, uint8_t *data, uint32_t size ); +}FragDecoderCallbacks_t; -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ /*! * \brief Initializes the fragmentation decoder * - * \param [in] fragNb Number of expected fragments (without redundancy packets) - * \param [in] fragSize Size of a fragment - * \param [in] callbacks Pointer to the Write/Read functions. + * \param [IN] fragNb Number of expected fragments (without redundancy packets) + * \param [IN] fragSize Size of a fragment + * \param [IN] callbacks Pointer to the Write/Read functions. */ -void FragDecoderInit(uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t *callbacks); +void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t *callbacks ); /*! * \brief Gets the maximum file size that can be received - * + * * \retval size FileSize */ -uint32_t FragDecoderGetMaxFileSize(void); +uint32_t FragDecoderGetMaxFileSize( void ); /*! * \brief Function to decode and reconstruct the binary file * Called for each receive frame - * - * \param [in] fragCounter Fragment counter [1..(FragDecoder.FragNb + FragDecoder.Redundancy)] - * \param [in] rawData Pointer to the fragment to be processed (length = FragDecoder.FragSize) + * + * \param [IN] fragCounter Fragment counter [1..(FragDecoder.FragNb + FragDecoder.Redundancy)] + * \param [IN] rawData Pointer to the fragment to be processed (length = FragDecoder.FragSize) * * \retval status Process status. [FRAG_SESSION_ONGOING, * FRAG_SESSION_FINISHED or * FragDecoder.Status.FragNbLost] */ -int32_t FragDecoderProcess(uint16_t fragCounter, uint8_t *rawData); +int32_t FragDecoderProcess( uint16_t fragCounter, uint8_t *rawData ); /*! * \brief Gets the current fragmentation status - * + * * \retval status Fragmentation decoder status */ -FragDecoderStatus_t FragDecoderGetStatus(void); - -#ifdef __cplusplus -} -#endif +FragDecoderStatus_t FragDecoderGetStatus( void ); -#endif /* __FRAG_DECODER_H__ */ +#endif // __FRAG_DECODER_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhPackage.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhPackage.h index d67b9200..0a70a312 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhPackage.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhPackage.h @@ -31,116 +31,108 @@ #ifndef __LMH_PACKAGE_H__ #define __LMH_PACKAGE_H__ -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ +#include +#include #include "LmHandlerTypes.h" -/* Exported defines ----------------------------------------------------------*/ /*! * Maximum number of packages */ #define PKG_MAX_NUMBER 5 -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/*! - * LoRaMac handler package parameters - */ typedef struct LmhPackage_s { - uint8_t Port; - /* - *========================================================================= - * Below callbacks must be initialized in package variable declaration - *========================================================================= - */ + uint8_t Port; + /* + *========================================================================= + * Below callbacks must be initialized in package variable declaration + *========================================================================= + */ - /*! - * Initializes the package with provided parameters - * - * \param [in] params Pointer to the package parameters - * \param [in] dataBuffer Pointer to main application buffer - * \param [in] dataBufferMaxSize Main application buffer maximum size - */ - void (*Init)(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize); - /*! - * Returns the current package initialization status. - * - * \retval status Package initialization status - * [true: Initialized, false: Not initialized] - */ - bool (*IsInitialized)(void); - /*! - * Returns the package operation status. - * - * \retval status Package operation status - * [true: Running, false: Not running] - */ - bool (*IsRunning)(void); - /*! - * Processes the internal package events. - */ - void (*Process)(void); - /*! - * Processes the MCSP Confirm - * - * \param [in] mcpsConfirm MCPS confirmation primitive data - */ - void (*OnMcpsConfirmProcess)(McpsConfirm_t *mcpsConfirm); - /*! - * Processes the MCPS Indication - * - * \param [in] mcpsIndication MCPS indication primitive data - */ - void (*OnMcpsIndicationProcess)(McpsIndication_t *mcpsIndication); - /*! - * Processes the MLME Confirm - * - * \param [in] mlmeConfirm MLME confirmation primitive data - */ - void (*OnMlmeConfirmProcess)(MlmeConfirm_t *mlmeConfirm); + /*! + * Initializes the package with provided parameters + * + * \param [IN] params Pointer to the package parameters + * \param [IN] dataBuffer Pointer to main application buffer + * \param [IN] dataBufferMaxSize Main application buffer maximum size + */ + void ( *Init )( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ); + /*! + * Returns the current package initialization status. + * + * \retval status Package initialization status + * [true: Initialized, false: Not initialized] + */ + bool ( *IsInitialized )( void ); + /*! + * Returns the package operation status. + * + * \retval status Package operation status + * [true: Running, false: Not running] + */ + bool ( *IsRunning )( void ); + /*! + * Processes the internal package events. + */ + void ( *Process )( void ); + /*! + * Notify the LmHandler process through an event + */ + void ( *OnPackageProcessEvent )( void ); + /*! + * Processes the MCSP Confirm + * + * \param [IN] mcpsConfirm MCPS confirmation primitive data + */ + void ( *OnMcpsConfirmProcess )( McpsConfirm_t *mcpsConfirm ); + /*! + * Processes the MCPS Indication + * + * \param [IN] mcpsIndication MCPS indication primitive data + */ + void ( *OnMcpsIndicationProcess )( McpsIndication_t *mcpsIndication ); + /*! + * Processes the MLME Confirm + * + * \param [IN] mlmeConfirm MLME confirmation primitive data + */ + void ( *OnMlmeConfirmProcess )( MlmeConfirm_t *mlmeConfirm ); - /* - *========================================================================= - * Below callbacks must be initialized in LmHandler initialization with - * provideded LmHandlerSend and OnMacRequest functions - *========================================================================= - */ - - /*! - * \brief Join a LoRa Network in classA - * - * \note if the device is ABP, this is a pass through function - * - * \param [in] isOtaa Indicates which activation mode must be used - */ - void (*OnJoinRequest)(ActivationType_t mode); - /*! - * \brief Instructs the MAC layer to send a ClassA uplink - * - * \param [in] appData Data to be sent - * \param [in] isTxConfirmed Indicates if the uplink requires an acknowledgement - * - * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been - * processed else \ref LORAMAC_HANDLER_ERROR - */ - LmHandlerErrorStatus_t (*OnSendRequest)(LmHandlerAppData_t *appData, LmHandlerMsgTypes_t isTxConfirmed, TimerTime_t *nextTxIn, bool allowDelayedTx); - /*! - * \brief Requests network server time update - * - * \retval status Returns \ref LORAMAC_HANDLER_SET if joined else \ref LORAMAC_HANDLER_RESET - */ - LmHandlerErrorStatus_t (*OnDeviceTimeRequest)(void); -} LmhPackage_t; + /* + *========================================================================= + * Below callbacks must be initialized in LmHandler initialization with + * provideded LmHandlerSend and OnMacRequest functions + *========================================================================= + */ -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -#ifdef __cplusplus -} -#endif + /*! + * Join a LoRa Network in classA + * + * \Note if the device is ABP, this is a pass through function + * + * \param [IN] isOtaa Indicates which activation mode must be used + */ + void ( *OnJoinRequest )( ActivationType_t mode ); + /*! + * Instructs the MAC layer to send a ClassA uplink + * + * \param [IN] appData Data to be sent + * \param [IN] isTxConfirmed Indicates if the uplink requires an acknowledgement + * + * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been + * processed else \ref LORAMAC_HANDLER_ERROR + */ + LmHandlerErrorStatus_t ( *OnSendRequest )( LmHandlerAppData_t *appData, LmHandlerMsgTypes_t isTxConfirmed, TimerTime_t *nextTxIn, bool allowDelayedTx ); + /*! + * Requests network server time update + * + * \retval status Returns \ref LORAMAC_HANDLER_SET if joined else \ref LORAMAC_HANDLER_RESET + */ + LmHandlerErrorStatus_t ( *OnDeviceTimeRequest )( void ); + /*! + * Notifies the upper layer that the system time has been updated. + */ + void ( *OnSysTimeUpdate )( void ); +}LmhPackage_t; -#endif /* __LMH_PACKAGE_H__ */ +#endif // __LMH_PACKAGE_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.c index 86343395..f1c5d82f 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.c +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.c @@ -29,72 +29,69 @@ * @brief Clock Synchronisation Package definition ****************************************************************************** */ -/* Includes ------------------------------------------------------------------*/ +#include "systime.h" #include "LmHandler.h" #include "LmhpClockSync.h" #include "utilities.h" -/* Private typedef -----------------------------------------------------------*/ +/*! + * LoRaWAN Application Layer Clock Synchronization Specification + */ +#define CLOCK_SYNC_PORT 202 + +#define CLOCK_SYNC_ID 1 +#define CLOCK_SYNC_VERSION 1 + /*! * Package current context */ typedef struct LmhpClockSyncState_s { - bool Initialized; - bool IsRunning; - uint8_t DataBufferMaxSize; - uint8_t *DataBuffer; - union - { - uint8_t Value; - struct + bool Initialized; + bool IsRunning; + uint8_t DataBufferMaxSize; + uint8_t *DataBuffer; + union { - uint8_t TokenReq: 4; - uint8_t AnsRequired: 1; - uint8_t RFU: 3; - } Fields; - } TimeReqParam; - bool AppTimeReqPending; - bool AdrEnabledPrev; - uint8_t NbTransPrev; - uint8_t DataratePrev; - uint8_t NbTransmissions; -} LmhpClockSyncState_t; + uint8_t Value; + struct + { + uint8_t TokenReq: 4; + uint8_t AnsRequired: 1; + uint8_t RFU: 3; + }Fields; + }TimeReqParam; + bool AppTimeReqPending; + bool AdrEnabledPrev; + uint8_t NbTransPrev; + uint8_t DataratePrev; + uint8_t NbTransmissions; +}LmhpClockSyncState_t; typedef enum LmhpClockSyncMoteCmd_e { - CLOCK_SYNC_PKG_VERSION_ANS = 0x00, - CLOCK_SYNC_APP_TIME_REQ = 0x01, - CLOCK_SYNC_APP_TIME_PERIOD_ANS = 0x02, - CLOCK_SYNC_FORCE_RESYNC_ANS = 0x03, -} LmhpClockSyncMoteCmd_t; + CLOCK_SYNC_PKG_VERSION_ANS = 0x00, + CLOCK_SYNC_APP_TIME_REQ = 0x01, + CLOCK_SYNC_APP_TIME_PERIOD_ANS = 0x02, + CLOCK_SYNC_FORCE_RESYNC_ANS = 0x03, +}LmhpClockSyncMoteCmd_t; typedef enum LmhpClockSyncSrvCmd_e { - CLOCK_SYNC_PKG_VERSION_REQ = 0x00, - CLOCK_SYNC_APP_TIME_ANS = 0x01, - CLOCK_SYNC_APP_TIME_PERIOD_REQ = 0x02, - CLOCK_SYNC_FORCE_RESYNC_REQ = 0x03, -} LmhpClockSyncSrvCmd_t; - -/* Private define ------------------------------------------------------------*/ -/*! - * LoRaWAN Application Layer Clock Synchronization Specification - */ -#define CLOCK_SYNC_PORT 202 -#define CLOCK_SYNC_ID 1 -#define CLOCK_SYNC_VERSION 1 + CLOCK_SYNC_PKG_VERSION_REQ = 0x00, + CLOCK_SYNC_APP_TIME_ANS = 0x01, + CLOCK_SYNC_APP_TIME_PERIOD_REQ = 0x02, + CLOCK_SYNC_FORCE_RESYNC_REQ = 0x03, +}LmhpClockSyncSrvCmd_t; -/* Private macro -------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ /*! * Initializes the package with provided parameters * - * \param [in] params Pointer to the package parameters - * \param [in] dataBuffer Pointer to main application buffer - * \param [in] dataBufferMaxSize Main application buffer maximum size + * \param [IN] params Pointer to the package parameters + * \param [IN] dataBuffer Pointer to main application buffer + * \param [IN] dataBufferMaxSize Main application buffer maximum size */ -static void LmhpClockSyncInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize); +static void LmhpClockSyncInit( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ); /*! * Returns the current package initialization status. @@ -102,7 +99,7 @@ static void LmhpClockSyncInit(void *params, uint8_t *dataBuffer, uint8_t dataBuf * \retval status Package initialization status * [true: Initialized, false: Not initialized] */ -static bool LmhpClockSyncIsInitialized(void); +static bool LmhpClockSyncIsInitialized( void ); /*! * Returns the package operation status. @@ -110,54 +107,55 @@ static bool LmhpClockSyncIsInitialized(void); * \retval status Package operation status * [true: Running, false: Not running] */ -static bool LmhpClockSyncIsRunning(void); +static bool LmhpClockSyncIsRunning( void ); /*! * Processes the internal package events. */ -static void LmhpClockSyncProcess(void); +static void LmhpClockSyncProcess( void ); /*! * Processes the MCSP Confirm * - * \param [in] mcpsConfirm MCPS confirmation primitive data + * \param [IN] mcpsConfirm MCPS confirmation primitive data */ -static void LmhpClockSyncOnMcpsConfirm(McpsConfirm_t *mcpsConfirm); +static void LmhpClockSyncOnMcpsConfirm( McpsConfirm_t *mcpsConfirm ); /*! * Processes the MCPS Indication * - * \param [in] mcpsIndication MCPS indication primitive data + * \param [IN] mcpsIndication MCPS indication primitive data */ -static void LmhpClockSyncOnMcpsIndication(McpsIndication_t *mcpsIndication); +static void LmhpClockSyncOnMcpsIndication( McpsIndication_t *mcpsIndication ); static void OnPeriodicTimeStartTimer(void *context); -/* Private variables ---------------------------------------------------------*/ static LmhpClockSyncState_t LmhpClockSyncState = { - .Initialized = false, - .IsRunning = false, - .TimeReqParam.Value = 0, - .AppTimeReqPending = false, - .AdrEnabledPrev = false, - .NbTransPrev = 0, - .NbTransmissions = 0 + .Initialized = false, + .IsRunning = false, + .TimeReqParam.Value = 0, + .AppTimeReqPending = false, + .AdrEnabledPrev = false, + .NbTransPrev = 0, + .NbTransmissions = 0, }; static LmhPackage_t LmhpClockSyncPackage = { - .Port = CLOCK_SYNC_PORT, - .Init = LmhpClockSyncInit, - .IsInitialized = LmhpClockSyncIsInitialized, - .IsRunning = LmhpClockSyncIsRunning, - .Process = LmhpClockSyncProcess, - .OnMcpsConfirmProcess = LmhpClockSyncOnMcpsConfirm, - .OnMcpsIndicationProcess = LmhpClockSyncOnMcpsIndication, - .OnMlmeConfirmProcess = NULL, /* Not used in this package */ - .OnJoinRequest = NULL, /* To be initialized by LmHandler */ - .OnSendRequest = NULL, /* To be initialized by LmHandler */ - .OnDeviceTimeRequest = NULL, /* To be initialized by LmHandler */ + .Port = CLOCK_SYNC_PORT, + .Init = LmhpClockSyncInit, + .IsInitialized = LmhpClockSyncIsInitialized, + .IsRunning = LmhpClockSyncIsRunning, + .Process = LmhpClockSyncProcess, + .OnMcpsConfirmProcess = LmhpClockSyncOnMcpsConfirm, + .OnMcpsIndicationProcess = LmhpClockSyncOnMcpsIndication, + .OnMlmeConfirmProcess = NULL, // Not used in this package + .OnJoinRequest = NULL, // To be initialized by LmHandler + .OnSendRequest = NULL, // To be initialized by LmHandler + .OnDeviceTimeRequest = NULL, // To be initialized by LmHandler + .OnSysTimeUpdate = NULL, // To be initialized by LmHandler + .OnPackageProcessEvent = NULL, // To be initialized by LmHandler }; /*! @@ -165,250 +163,264 @@ static LmhPackage_t LmhpClockSyncPackage = */ static TimerEvent_t PeriodicTimeStartTimer; -/* Exported functions ---------------------------------------------------------*/ -LmhPackage_t *LmphClockSyncPackageFactory(void) +LmhPackage_t *LmhpClockSyncPackageFactory( void ) { - return &LmhpClockSyncPackage; -} - -LmHandlerErrorStatus_t LmhpClockSyncAppTimeReq(void) -{ - if (LmHandlerIsBusy() == true) - { - return LORAMAC_HANDLER_ERROR; - } - - if (LmhpClockSyncState.AppTimeReqPending == false) - { - MibRequestConfirm_t mibReq; - - /* Disable ADR */ - mibReq.Type = MIB_ADR; - LoRaMacMibGetRequestConfirm(&mibReq); - LmhpClockSyncState.AdrEnabledPrev = mibReq.Param.AdrEnable; - mibReq.Param.AdrEnable = false; - LoRaMacMibSetRequestConfirm(&mibReq); - - /* Set NbTrans = 1 */ - mibReq.Type = MIB_CHANNELS_NB_TRANS; - LoRaMacMibGetRequestConfirm(&mibReq); - LmhpClockSyncState.NbTransPrev = mibReq.Param.ChannelsNbTrans; - mibReq.Param.ChannelsNbTrans = 1; - LoRaMacMibSetRequestConfirm(&mibReq); - - /* Store data rate */ - mibReq.Type = MIB_CHANNELS_DATARATE; - LoRaMacMibGetRequestConfirm(&mibReq); - LmhpClockSyncState.DataratePrev = mibReq.Param.ChannelsDatarate; - - /* Add DeviceTimeReq MAC command. */ - /* In case the network server supports this more precise command */ - /* this package will use DeviceTimeAns answer as clock synchronization */ - /* mechanism. */ - LmhpClockSyncPackage.OnDeviceTimeRequest(); - } - - SysTime_t curTime = SysTimeGet(); - uint8_t dataBufferIndex = 0; - - /* Subtract Unix to Gps epcoh offset. The system time is based on Unix time. */ - curTime.Seconds -= UNIX_GPS_EPOCH_OFFSET; - - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_APP_TIME_REQ; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 0) & 0xFF; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 8) & 0xFF; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 16) & 0xFF; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 24) & 0xFF; - LmhpClockSyncState.TimeReqParam.Fields.AnsRequired = 0; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = LmhpClockSyncState.TimeReqParam.Value; - - LmHandlerAppData_t appData = - { - .Buffer = LmhpClockSyncState.DataBuffer, - .BufferSize = dataBufferIndex, - .Port = CLOCK_SYNC_PORT - }; - LmhpClockSyncState.AppTimeReqPending = true; - - bool current_dutycycle; - LmHandlerGetDutyCycleEnable(¤t_dutycycle); - - /* force Duty Cycle OFF to this Send */ - LmHandlerSetDutyCycleEnable(false); - LmHandlerErrorStatus_t status = LmhpClockSyncPackage.OnSendRequest(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); - - /* restore initial Duty Cycle */ - LmHandlerSetDutyCycleEnable(current_dutycycle); - - return status; + return &LmhpClockSyncPackage; } -/* Private functions ---------------------------------------------------------*/ -static void LmhpClockSyncInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize) +static void LmhpClockSyncInit( void * params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ) { - if (dataBuffer != NULL) - { - LmhpClockSyncState.DataBuffer = dataBuffer; - LmhpClockSyncState.DataBufferMaxSize = dataBufferMaxSize; - LmhpClockSyncState.Initialized = true; - LmhpClockSyncState.IsRunning = true; - TimerInit(&PeriodicTimeStartTimer, OnPeriodicTimeStartTimer); - } - else - { - LmhpClockSyncState.IsRunning = false; - LmhpClockSyncState.Initialized = false; - } + if( dataBuffer != NULL ) + { + LmhpClockSyncState.DataBuffer = dataBuffer; + LmhpClockSyncState.DataBufferMaxSize = dataBufferMaxSize; + LmhpClockSyncState.Initialized = true; + LmhpClockSyncState.IsRunning = true; + TimerInit(&PeriodicTimeStartTimer, OnPeriodicTimeStartTimer); + } + else + { + LmhpClockSyncState.IsRunning = false; + LmhpClockSyncState.Initialized = false; + } } -static bool LmhpClockSyncIsInitialized(void) +static bool LmhpClockSyncIsInitialized( void ) { - return LmhpClockSyncState.Initialized; + return LmhpClockSyncState.Initialized; } -static bool LmhpClockSyncIsRunning(void) +static bool LmhpClockSyncIsRunning( void ) { - if (LmhpClockSyncState.Initialized == false) - { - return false; - } + if( LmhpClockSyncState.Initialized == false ) + { + return false; + } - return LmhpClockSyncState.IsRunning; + return LmhpClockSyncState.IsRunning; } -static void LmhpClockSyncProcess(void) +static void LmhpClockSyncProcess( void ) { - if (LmhpClockSyncState.NbTransmissions > 0) - { - if (LmhpClockSyncAppTimeReq() == LORAMAC_HANDLER_SUCCESS) + if( LmhpClockSyncState.NbTransmissions > 0 ) { - LmhpClockSyncState.NbTransmissions--; + if( LmhpClockSyncAppTimeReq( ) == LORAMAC_HANDLER_SUCCESS ) + { + LmhpClockSyncState.NbTransmissions--; + } } - } } -static void LmhpClockSyncOnMcpsConfirm(McpsConfirm_t *mcpsConfirm) +static void LmhpClockSyncOnMcpsConfirm( McpsConfirm_t *mcpsConfirm ) { - MibRequestConfirm_t mibReq; - - if (LmhpClockSyncState.AppTimeReqPending == true) - { - /* Revert ADR setting */ - mibReq.Type = MIB_ADR; - mibReq.Param.AdrEnable = LmhpClockSyncState.AdrEnabledPrev; - LoRaMacMibSetRequestConfirm(&mibReq); - - /* Revert NbTrans setting */ - mibReq.Type = MIB_CHANNELS_NB_TRANS; - mibReq.Param.ChannelsNbTrans = LmhpClockSyncState.NbTransPrev; - LoRaMacMibSetRequestConfirm(&mibReq); - - /* Revert data rate setting */ - mibReq.Type = MIB_CHANNELS_DATARATE; - mibReq.Param.ChannelsDatarate = LmhpClockSyncState.DataratePrev; - LoRaMacMibSetRequestConfirm(&mibReq); - - LmhpClockSyncState.AppTimeReqPending = false; - } + MibRequestConfirm_t mibReq; + + if( LmhpClockSyncState.AppTimeReqPending == true ) + { + // Revert ADR setting + mibReq.Type = MIB_ADR; + mibReq.Param.AdrEnable = LmhpClockSyncState.AdrEnabledPrev; + LoRaMacMibSetRequestConfirm( &mibReq ); + + // Revert NbTrans setting + mibReq.Type = MIB_CHANNELS_NB_TRANS; + mibReq.Param.ChannelsNbTrans = LmhpClockSyncState.NbTransPrev; + LoRaMacMibSetRequestConfirm( &mibReq ); + + // Revert data rate setting + mibReq.Type = MIB_CHANNELS_DATARATE; + mibReq.Param.ChannelsDatarate = LmhpClockSyncState.DataratePrev; + LoRaMacMibSetRequestConfirm( &mibReq ); + + LmhpClockSyncState.AppTimeReqPending = false; + } } -static void LmhpClockSyncOnMcpsIndication(McpsIndication_t *mcpsIndication) +static void LmhpClockSyncOnMcpsIndication( McpsIndication_t *mcpsIndication ) { - uint8_t cmdIndex = 0; - uint8_t dataBufferIndex = 0; + uint8_t cmdIndex = 0; + uint8_t dataBufferIndex = 0; + + if( mcpsIndication->Port != CLOCK_SYNC_PORT ) + { + return; + } - while (cmdIndex < mcpsIndication->BufferSize) - { - switch (mcpsIndication->Buffer[cmdIndex++]) + while( cmdIndex < mcpsIndication->BufferSize ) { - case CLOCK_SYNC_PKG_VERSION_REQ: - { - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_PKG_VERSION_ANS; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_ID; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_VERSION; - break; - } - case CLOCK_SYNC_APP_TIME_ANS: - { - LmhpClockSyncState.NbTransmissions = 0; - - /* Check if a more precise time correction has been received. */ - /* If yes then don't process and ignore this answer. */ - if (mcpsIndication->DeviceTimeAnsReceived == true) + switch( mcpsIndication->Buffer[cmdIndex++] ) { - cmdIndex += 5; - break; + case CLOCK_SYNC_PKG_VERSION_REQ: + { + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_PKG_VERSION_ANS; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_ID; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_VERSION; + break; + } + case CLOCK_SYNC_APP_TIME_ANS: + { + LmhpClockSyncState.NbTransmissions = 0; + + // Check if a more precise time correction has been received. + // If yes then don't process and ignore this answer. + if( mcpsIndication->DeviceTimeAnsReceived == true ) + { + cmdIndex += 5; + break; + } + int32_t timeCorrection = 0; + timeCorrection = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF; + timeCorrection += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00; + timeCorrection += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000; + timeCorrection += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000; + if( ( mcpsIndication->Buffer[cmdIndex++] & 0x0F ) == LmhpClockSyncState.TimeReqParam.Fields.TokenReq ) + { + SysTime_t curTime = { .Seconds = 0, .SubSeconds = 0 }; + curTime = SysTimeGet( ); + curTime.Seconds += timeCorrection; + SysTimeSet( curTime ); + LmhpClockSyncState.TimeReqParam.Fields.TokenReq = ( LmhpClockSyncState.TimeReqParam.Fields.TokenReq + 1 ) & 0x0F; + if( LmhpClockSyncPackage.OnSysTimeUpdate != NULL ) + { + if( ( timeCorrection >= -1 ) && ( timeCorrection <= 1 ) ) + { + LmhpClockSyncPackage.OnSysTimeUpdate( ); + } + } + } + break; + } + case CLOCK_SYNC_APP_TIME_PERIOD_REQ: + { + // Increment index + cmdIndex++; + + uint32_t periodTime = mcpsIndication->Buffer[cmdIndex++] & 0x0F; + periodTime = (128 << periodTime) + randr(0, 30); + + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_APP_TIME_PERIOD_ANS; + // Answer status supported. + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = 0x00; + + SysTime_t curTime = SysTimeGet( ); + // Substract Unix to Gps epoch offset. The system time is based on Unix time. + curTime.Seconds -= UNIX_GPS_EPOCH_OFFSET; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 0 ) & 0xFF; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 8 ) & 0xFF; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 16 ) & 0xFF; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 24 ) & 0xFF; + + /* Start Periodic timer */ + TimerSetValue(&PeriodicTimeStartTimer, periodTime * 1000); + TimerStart(&PeriodicTimeStartTimer); + + break; + } + case CLOCK_SYNC_FORCE_RESYNC_REQ: + { + LmhpClockSyncState.NbTransmissions = mcpsIndication->Buffer[cmdIndex++] & 0X07; + break; + } } - int32_t timeCorrection = 0; - timeCorrection = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x000000FF; - timeCorrection += (mcpsIndication->Buffer[cmdIndex++] << 8) & 0x0000FF00; - timeCorrection += (mcpsIndication->Buffer[cmdIndex++] << 16) & 0x00FF0000; - timeCorrection += (mcpsIndication->Buffer[cmdIndex++] << 24) & 0xFF000000; - if ((mcpsIndication->Buffer[cmdIndex++] & 0x0F) == LmhpClockSyncState.TimeReqParam.Fields.TokenReq) + } + + if( dataBufferIndex != 0 ) + { + // Answer commands + LmHandlerAppData_t appData = { - SysTime_t curTime = { .Seconds = 0, .SubSeconds = 0 }; - curTime = SysTimeGet(); - curTime.Seconds += timeCorrection; - SysTimeSet(curTime); - LmhpClockSyncState.TimeReqParam.Fields.TokenReq = (LmhpClockSyncState.TimeReqParam.Fields.TokenReq + 1) & 0x0F; - } - break; - } - case CLOCK_SYNC_APP_TIME_PERIOD_REQ: - { - uint32_t periodTime = mcpsIndication->Buffer[cmdIndex++] & 0x0F; - periodTime = (128 << periodTime) + randr(0, 30); - - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_APP_TIME_PERIOD_ANS; - /* Answer status supported. */ - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = 0x00; - - SysTime_t curTime = SysTimeGet(); - /* Subtract Unix to Gps epcoh offset. The system time is based on Unix time. */ - curTime.Seconds -= UNIX_GPS_EPOCH_OFFSET; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 0) & 0xFF; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 8) & 0xFF; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 16) & 0xFF; - LmhpClockSyncState.DataBuffer[dataBufferIndex++] = (curTime.Seconds >> 24) & 0xFF; - - /* Start Periodic timer */ - TimerSetValue(&PeriodicTimeStartTimer, periodTime * 1000); - TimerStart(&PeriodicTimeStartTimer); - - break; - } - case CLOCK_SYNC_FORCE_RESYNC_REQ: - { - LmhpClockSyncState.NbTransmissions = mcpsIndication->Buffer[cmdIndex++] & 0X07; - break; - } + .Buffer = LmhpClockSyncState.DataBuffer, + .BufferSize = dataBufferIndex, + .Port = CLOCK_SYNC_PORT + }; + + bool current_dutycycle; + LmHandlerGetDutyCycleEnable(¤t_dutycycle); + + /* force Duty Cycle OFF to this Send */ + LmHandlerSetDutyCycleEnable(false); + LmhpClockSyncPackage.OnSendRequest(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); + + /* restore initial Duty Cycle */ + LmHandlerSetDutyCycleEnable(current_dutycycle); + } +} + +LmHandlerErrorStatus_t LmhpClockSyncAppTimeReq( void ) +{ + if( LmHandlerIsBusy( ) == true ) + { + return LORAMAC_HANDLER_ERROR; } - } - if (dataBufferIndex != 0) - { - /* Answer commands */ + if( LmhpClockSyncState.AppTimeReqPending == false ) + { + MibRequestConfirm_t mibReq; + + // Disable ADR + mibReq.Type = MIB_ADR; + LoRaMacMibGetRequestConfirm( &mibReq ); + LmhpClockSyncState.AdrEnabledPrev = mibReq.Param.AdrEnable; + mibReq.Param.AdrEnable = false; + LoRaMacMibSetRequestConfirm( &mibReq ); + + // Set NbTrans = 1 + mibReq.Type = MIB_CHANNELS_NB_TRANS; + LoRaMacMibGetRequestConfirm( &mibReq ); + LmhpClockSyncState.NbTransPrev = mibReq.Param.ChannelsNbTrans; + mibReq.Param.ChannelsNbTrans = 1; + LoRaMacMibSetRequestConfirm( &mibReq ); + + // Store data rate + mibReq.Type = MIB_CHANNELS_DATARATE; + LoRaMacMibGetRequestConfirm( &mibReq ); + LmhpClockSyncState.DataratePrev = mibReq.Param.ChannelsDatarate; + + // Add DeviceTimeReq MAC command. + // In case the network server supports this more precise command + // this package will use DeviceTimeAns answer as clock synchronization + // mechanism. + LmhpClockSyncPackage.OnDeviceTimeRequest( ); + } + + SysTime_t curTime = SysTimeGet( ); + uint8_t dataBufferIndex = 0; + + // Substract Unix to Gps epoch offset. The system time is based on Unix time. + curTime.Seconds -= UNIX_GPS_EPOCH_OFFSET; + + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = CLOCK_SYNC_APP_TIME_REQ; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 0 ) & 0xFF; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 8 ) & 0xFF; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 16 ) & 0xFF; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = ( curTime.Seconds >> 24 ) & 0xFF; + LmhpClockSyncState.TimeReqParam.Fields.AnsRequired = 0; + LmhpClockSyncState.DataBuffer[dataBufferIndex++] = LmhpClockSyncState.TimeReqParam.Value; + LmHandlerAppData_t appData = { - .Buffer = LmhpClockSyncState.DataBuffer, - .BufferSize = dataBufferIndex, - .Port = CLOCK_SYNC_PORT + .Buffer = LmhpClockSyncState.DataBuffer, + .BufferSize = dataBufferIndex, + .Port = CLOCK_SYNC_PORT }; + LmhpClockSyncState.AppTimeReqPending = true; bool current_dutycycle; LmHandlerGetDutyCycleEnable(¤t_dutycycle); /* force Duty Cycle OFF to this Send */ LmHandlerSetDutyCycleEnable(false); - LmhpClockSyncPackage.OnSendRequest(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); + LmHandlerErrorStatus_t status = LmhpClockSyncPackage.OnSendRequest(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); /* restore initial Duty Cycle */ LmHandlerSetDutyCycleEnable(current_dutycycle); - } + + return status; } static void OnPeriodicTimeStartTimer(void *context) { LmhpClockSyncState.NbTransmissions = 1; TimerStart(&PeriodicTimeStartTimer); + LmhpClockSyncPackage.OnPackageProcessEvent(); } diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.h index d3e26660..254e211d 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpClockSync.h @@ -19,27 +19,13 @@ * * \author Miguel Luis ( Semtech ) */ -/** - ****************************************************************************** - * - * Portions COPYRIGHT 2020 STMicroelectronics - * - * @file LmhpClockSync.h - * @author MCD Application Team - * @brief Header for Clock Synchronisation Package module - ****************************************************************************** - */ #ifndef __LMHP_CLOCK_SYNC_H__ #define __LMHP_CLOCK_SYNC_H__ -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ +#include "LoRaMac.h" +#include "LmHandlerTypes.h" #include "LmhPackage.h" -/* Exported defines ----------------------------------------------------------*/ /*! * Clock sync package identifier. * @@ -47,17 +33,17 @@ extern "C" { */ #define PACKAGE_ID_CLOCK_SYNC 1 -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -LmhPackage_t *LmphClockSyncPackageFactory(void); +/*! + * Clock sync package parameters + * + * This package doesn't require parameters + */ +//typedef struct LmhpClockSyncParams_s +//{ +//}LmhpClockSyncParams_t; -LmHandlerErrorStatus_t LmhpClockSyncAppTimeReq(void); +LmhPackage_t *LmhpClockSyncPackageFactory( void ); -#ifdef __cplusplus -} -#endif +LmHandlerErrorStatus_t LmhpClockSyncAppTimeReq( void ); -#endif /* __LMHP_CLOCK_SYNC_H__ */ +#endif // __LMHP_CLOCK_SYNC_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.c index bcab48a5..cb30d15a 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.c +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.c @@ -28,32 +28,17 @@ * @brief Certification Protocol Handling definition ****************************************************************************** */ -/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include "utilities.h" +#include "timer.h" +#include "LoRaMac.h" #include "LoRaMacTest.h" +#include "Region.h" +#include "LmhPackage.h" #include "LmhpCompliance.h" -/* Private typedef -----------------------------------------------------------*/ -/*! - * LoRaWAN compliance tests support data - */ -typedef struct ComplianceTestState_s -{ - bool Initialized; - bool IsRunning; - uint8_t State; - bool TxPending; - bool IsTxConfirmed; - uint8_t Port; - uint8_t DataBufferMaxSize; - uint8_t DataBufferSize; - uint8_t *DataBuffer; - uint16_t DownLinkCounter; - bool LinkCheck; - uint8_t DemodMargin; - uint8_t NbGateways; -} ComplianceTestState_t; - -/* Private define ------------------------------------------------------------*/ /*! * LoRaWAN compliance certification protocol port number. * @@ -67,21 +52,67 @@ typedef struct ComplianceTestState_s */ #define COMPLIANCE_TX_DUTYCYCLE 5000 -/* Private macro -------------------------------------------------------------*/ +/*! + * LoRaWAN compliance tests support data + */ +typedef struct ComplianceTestState_s +{ + bool Initialized; + bool IsRunning; + uint8_t State; + bool IsTxConfirmed; + uint8_t Port; + uint8_t DataBufferMaxSize; + uint8_t DataBufferSize; + uint8_t *DataBuffer; + uint16_t DownLinkCounter; + bool LinkCheck; + uint8_t DemodMargin; + uint8_t NbGateways; +}ComplianceTestState_t; + #ifndef MIN #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) #endif -/* Private function prototypes -----------------------------------------------*/ +/*! + * Timer to handle the application data transmission duty cycle + */ +static TimerEvent_t ComplianceTxNextPacketTimer; + +/*! + * Holds the compliance test current context + */ +static ComplianceTestState_t ComplianceTestState = +{ + .Initialized = false, + .IsRunning = false, + .State = 0, + .IsTxConfirmed = false, + .Port = 0, + .DataBufferMaxSize = 0, + .DataBufferSize = 0, + .DataBuffer = NULL, + .DownLinkCounter = 0, + .LinkCheck = false, + .DemodMargin = 0, + .NbGateways = 0 +}; + +/*! + * LoRaWAN compliance tests protocol handler parameters + */ +static LmhpComplianceParams_t* LmhpComplianceParams; + /*! * Initializes the compliance tests with provided parameters * - * \param [in] params Structure containing the initial compliance + * \param [IN] params Structure containing the initial compliance * tests parameters. - * \param [in] dataBuffer Pointer to main application buffer - * \param [in] dataBufferMaxSize Application buffer maximum size + * \param [IN] dataBuffer Pointer to main application buffer + * \param [IN] dataBufferMaxSize Application buffer maximum size */ -static void LmhpComplianceInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize); +static void LmhpComplianceInit( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ); /*! * Returns the current compliance certification protocol initialization status. @@ -89,7 +120,7 @@ static void LmhpComplianceInit(void *params, uint8_t *dataBuffer, uint8_t dataBu * \retval status Compliance certification protocol initialization status * [true: Initialized, false: Not initialized] */ -static bool LmhpComplianceIsInitialized(void); +static bool LmhpComplianceIsInitialized( void ); /*! * Returns the current compliance certification protocol handling status. @@ -97,12 +128,12 @@ static bool LmhpComplianceIsInitialized(void); * \retval status Compliance certification protocol handling status * [true: Running, false: Not running] */ -static bool LmhpComplianceIsRunning(void); +static bool LmhpComplianceIsRunning( void ); /*! * Processes the LoRaMac Compliance events. */ -static void LmhpComplianceProcess(void); +static void LmhpComplianceProcess( void ); /*! * Processes the MCPS Confirm @@ -114,21 +145,21 @@ static void LmhpComplianceOnMcpsConfirm(McpsConfirm_t *mcpsConfirm); /*! * Processes the MCPS Indication * - * \param [in] mcpsIndication MCPS indication primitive data + * \param [IN] mcpsIndication MCPS indication primitive data */ -static void LmhpComplianceOnMcpsIndication(McpsIndication_t *mcpsIndication); +static void LmhpComplianceOnMcpsIndication( McpsIndication_t *mcpsIndication ); /*! * Processes the MLME Confirm * - * \param [in] mlmeConfirm MLME confirmation primitive data + * \param [IN] mlmeConfirm MLME confirmation primitive data */ -static void LmhpComplianceOnMlmeConfirm(MlmeConfirm_t *mlmeConfirm); +static void LmhpComplianceOnMlmeConfirm( MlmeConfirm_t *mlmeConfirm ); /*! * Function executed on TxNextPacket Timeout event */ -static void OnComplianceTxNextPacketTimerEvent(void *context); +static void OnComplianceTxNextPacketTimerEvent( void *context ); /*! * Processes the data to transmit on port \ref COMPLIANCE_PORT @@ -137,382 +168,362 @@ static void OnComplianceTxNextPacketTimerEvent(void *context); * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been * processed else \ref LORAMAC_HANDLER_ERROR */ -static LmHandlerErrorStatus_t LmhpComplianceTxProcess(void); - -/* Private variables ---------------------------------------------------------*/ -/*! - * Timer to handle the application data transmission duty cycle - */ -static TimerEvent_t ComplianceTxNextPacketTimer; - -/*! - * Holds the compliance test current context - */ -static ComplianceTestState_t ComplianceTestState = -{ - .Initialized = false, - .IsRunning = false, - .State = 0, - .IsTxConfirmed = false, - .Port = 0, - .DataBufferMaxSize = 0, - .DataBufferSize = 0, - .DataBuffer = NULL, - .DownLinkCounter = 0, - .LinkCheck = false, - .DemodMargin = 0, - .NbGateways = 0 -}; - -/*! - * LoRaWAN compliance tests protocol handler parameters - */ -static LmhpComplianceParams_t *LmhpComplianceParams; +static LmHandlerErrorStatus_t LmhpComplianceTxProcess( void ); static LmhPackage_t LmhpCompliancePackage = { - .Port = COMPLIANCE_PORT, - .Init = LmhpComplianceInit, - .IsInitialized = LmhpComplianceIsInitialized, - .IsRunning = LmhpComplianceIsRunning, - .Process = LmhpComplianceProcess, - .OnMcpsConfirmProcess = LmhpComplianceOnMcpsConfirm, - .OnMcpsIndicationProcess = LmhpComplianceOnMcpsIndication, - .OnMlmeConfirmProcess = LmhpComplianceOnMlmeConfirm, - .OnJoinRequest = NULL, /* To be initialized by LmHandler */ - .OnSendRequest = NULL, /* To be initialized by LmHandler */ - .OnDeviceTimeRequest = NULL, /* To be initialized by LmHandler */ + .Port = COMPLIANCE_PORT, + .Init = LmhpComplianceInit, + .IsInitialized = LmhpComplianceIsInitialized, + .IsRunning = LmhpComplianceIsRunning, + .Process = LmhpComplianceProcess, + .OnMcpsConfirmProcess = LmhpComplianceOnMcpsConfirm, + .OnMcpsIndicationProcess = LmhpComplianceOnMcpsIndication, + .OnMlmeConfirmProcess = LmhpComplianceOnMlmeConfirm, + .OnJoinRequest = NULL, // To be initialized by LmHandler + .OnSendRequest = NULL, // To be initialized by LmHandler + .OnDeviceTimeRequest = NULL, // To be initialized by LmHandler + .OnSysTimeUpdate = NULL, // To be initialized by LmHandler + .OnPackageProcessEvent = NULL, // To be initialized by LmHandler }; -/* Exported functions ---------------------------------------------------------*/ -LmhPackage_t *LmphCompliancePackageFactory(void) +LmhPackage_t *LmhpCompliancePackageFactory( void ) { - return &LmhpCompliancePackage; + return &LmhpCompliancePackage; } -/* Private functions ---------------------------------------------------------*/ -static void LmhpComplianceInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize) +static void LmhpComplianceInit( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ) { - if ((params != NULL) && (dataBuffer != NULL)) - { - LmhpComplianceParams = (LmhpComplianceParams_t *)params; - ComplianceTestState.DataBuffer = dataBuffer; - ComplianceTestState.DataBufferMaxSize = dataBufferMaxSize; - ComplianceTestState.Initialized = true; - } - else - { - LmhpComplianceParams = NULL; - ComplianceTestState.Initialized = false; - } + if( ( params != NULL ) && ( dataBuffer != NULL ) ) + { + LmhpComplianceParams = ( LmhpComplianceParams_t* )params; + ComplianceTestState.DataBuffer = dataBuffer; + ComplianceTestState.DataBufferMaxSize = dataBufferMaxSize; + ComplianceTestState.Initialized = true; + } + else + { + LmhpComplianceParams = NULL; + ComplianceTestState.Initialized = false; + } } -static bool LmhpComplianceIsInitialized(void) +static bool LmhpComplianceIsInitialized( void ) { - return ComplianceTestState.Initialized; + return ComplianceTestState.Initialized; } -static bool LmhpComplianceIsRunning(void) +static bool LmhpComplianceIsRunning( void ) { - if (ComplianceTestState.Initialized == false) - { - return false; - } + if( ComplianceTestState.Initialized == false ) + { + return false; + } - return ComplianceTestState.IsRunning; + return ComplianceTestState.IsRunning; } static void LmhpComplianceOnMcpsConfirm(McpsConfirm_t *mcpsConfirm) { - if (ComplianceTestState.Initialized == false) - { - return; - } - - if ((ComplianceTestState.IsRunning == true) && - (mcpsConfirm->McpsRequest == MCPS_CONFIRMED) && - (mcpsConfirm->AckReceived != 0)) - { - /* Increment the compliance certification protocol downlink counter */ - ComplianceTestState.DownLinkCounter++; - } -} - -static void LmhpComplianceOnMlmeConfirm(MlmeConfirm_t *mlmeConfirm) -{ - if (ComplianceTestState.Initialized == false) - { - return; - } - - if (mlmeConfirm->MlmeRequest == MLME_LINK_CHECK) - { - ComplianceTestState.LinkCheck = true; - ComplianceTestState.DemodMargin = mlmeConfirm->DemodMargin; - ComplianceTestState.NbGateways = mlmeConfirm->NbGateways; - } -} + if (ComplianceTestState.Initialized == false) + { + return; + } -static LmHandlerErrorStatus_t LmhpComplianceTxProcess(void) -{ - if (ComplianceTestState.Initialized == false) - { - return LORAMAC_HANDLER_ERROR; - } - - if (ComplianceTestState.LinkCheck == true) - { - ComplianceTestState.LinkCheck = false; - ComplianceTestState.DataBufferSize = 3; - ComplianceTestState.DataBuffer[0] = 5; - ComplianceTestState.DataBuffer[1] = ComplianceTestState.DemodMargin; - ComplianceTestState.DataBuffer[2] = ComplianceTestState.NbGateways; - ComplianceTestState.State = 1; - } - else - { - switch (ComplianceTestState.State) + if ((ComplianceTestState.IsRunning == true) && + (mcpsConfirm->McpsRequest == MCPS_CONFIRMED) && + (mcpsConfirm->AckReceived != 0)) { - case 4: - ComplianceTestState.State = 1; - break; - case 1: - ComplianceTestState.DataBufferSize = 2; - ComplianceTestState.DataBuffer[0] = ComplianceTestState.DownLinkCounter >> 8; - ComplianceTestState.DataBuffer[1] = ComplianceTestState.DownLinkCounter; - break; + /* Increment the compliance certification protocol downlink counter */ + ComplianceTestState.DownLinkCounter++; } - } - LmHandlerAppData_t appData = - { - .Buffer = ComplianceTestState.DataBuffer, - .BufferSize = ComplianceTestState.DataBufferSize, - .Port = COMPLIANCE_PORT - }; - TimerTime_t nextTxIn = 0; - - /* Schedule next transmission */ - TimerStart(&ComplianceTxNextPacketTimer); - - return LmhpCompliancePackage.OnSendRequest(&appData, (LmHandlerMsgTypes_t)ComplianceTestState.IsTxConfirmed, &nextTxIn, - true); } -static void LmhpComplianceOnMcpsIndication(McpsIndication_t *mcpsIndication) +static void LmhpComplianceOnMlmeConfirm( MlmeConfirm_t *mlmeConfirm ) { - if (ComplianceTestState.Initialized == false) - { - return; - } - - if (mcpsIndication->RxData == false) - { - return; - } - - if ((ComplianceTestState.IsRunning == true) && - (mcpsIndication->AckReceived == 0)) - { - /* Increment the compliance certification protocol downlink counter */ - ComplianceTestState.DownLinkCounter++; - } - - if (mcpsIndication->Port != COMPLIANCE_PORT) - { - return; - } - - if (ComplianceTestState.IsRunning == false) - { - /* Check compliance test enable command (i) */ - if ((mcpsIndication->BufferSize == 4) && - (mcpsIndication->Buffer[0] == 0x01) && - (mcpsIndication->Buffer[1] == 0x01) && - (mcpsIndication->Buffer[2] == 0x01) && - (mcpsIndication->Buffer[3] == 0x01)) + if( ComplianceTestState.Initialized == false ) { - MibRequestConfirm_t mibReq; - - /* Initialize compliance test mode context */ - ComplianceTestState.IsTxConfirmed = false; - ComplianceTestState.Port = 224; - ComplianceTestState.DataBufferSize = 2; - ComplianceTestState.DownLinkCounter = 0; - ComplianceTestState.LinkCheck = false; - ComplianceTestState.DemodMargin = 0; - ComplianceTestState.NbGateways = 0; - ComplianceTestState.IsRunning = true; - ComplianceTestState.State = 1; - - /* Enable ADR while in compliance test mode */ - mibReq.Type = MIB_ADR; - mibReq.Param.AdrEnable = true; - LoRaMacMibSetRequestConfirm(&mibReq); - - /* Disable duty cycle enforcement while in compliance test mode */ - LoRaMacTestSetDutyCycleOn(false); - - /* Stop peripherals */ - if (LmhpComplianceParams->StopPeripherals != NULL) - { - LmhpComplianceParams->StopPeripherals(); - } - /* Initialize compliance protocol transmission timer */ - TimerInit(&ComplianceTxNextPacketTimer, OnComplianceTxNextPacketTimerEvent); - TimerSetValue(&ComplianceTxNextPacketTimer, COMPLIANCE_TX_DUTYCYCLE); - - /* Confirm compliance test protocol activation */ - LmhpComplianceTxProcess(); + return; } - } - else - { - /* Parse compliance test protocol */ - ComplianceTestState.State = mcpsIndication->Buffer[0]; - switch (ComplianceTestState.State) - { - case 0: /* Check compliance test disable command (ii) */ - { - MibRequestConfirm_t mibReq; - TimerStop(&ComplianceTxNextPacketTimer); + if( ComplianceTestState.IsRunning == false ) + { + return; + } - /* Disable compliance test mode and reset the downlink counter. */ - ComplianceTestState.DownLinkCounter = 0; - ComplianceTestState.IsRunning = false; + if( mlmeConfirm->MlmeRequest == MLME_LINK_CHECK ) + { + ComplianceTestState.LinkCheck = true; + ComplianceTestState.DemodMargin = mlmeConfirm->DemodMargin; + ComplianceTestState.NbGateways = mlmeConfirm->NbGateways; + } +} - /* Restore previous ADR seeting */ - mibReq.Type = MIB_ADR; - mibReq.Param.AdrEnable = LmhpComplianceParams->AdrEnabled; - LoRaMacMibSetRequestConfirm(&mibReq); +static LmHandlerErrorStatus_t LmhpComplianceTxProcess( void ) +{ + if( ComplianceTestState.Initialized == false ) + { + return LORAMAC_HANDLER_ERROR; + } - /* Enable duty cycle enforcement */ - LoRaMacTestSetDutyCycleOn(LmhpComplianceParams->DutyCycleEnabled); + if( ComplianceTestState.IsRunning == false ) + { + return LORAMAC_HANDLER_SUCCESS; + } - /* Restart peripherals */ - if (LmhpComplianceParams->StartPeripherals != NULL) - { - LmhpComplianceParams->StartPeripherals(); - } - } - break; - case 1: /* (iii, iv) */ - ComplianceTestState.DataBufferSize = 2; - break; - case 2: /* Enable confirmed messages (v) */ - ComplianceTestState.IsTxConfirmed = true; - ComplianceTestState.State = 1; - break; - case 3: /* Disable confirmed messages (vi) */ - ComplianceTestState.IsTxConfirmed = false; + if( ComplianceTestState.LinkCheck == true ) + { + ComplianceTestState.LinkCheck = false; + ComplianceTestState.DataBufferSize = 3; + ComplianceTestState.DataBuffer[0] = 5; + ComplianceTestState.DataBuffer[1] = ComplianceTestState.DemodMargin; + ComplianceTestState.DataBuffer[2] = ComplianceTestState.NbGateways; ComplianceTestState.State = 1; - break; - case 4: /* (vii) */ - ComplianceTestState.DataBufferSize = mcpsIndication->BufferSize; - - ComplianceTestState.DataBuffer[0] = 4; - for (uint8_t i = 1; i < MIN(ComplianceTestState.DataBufferSize, ComplianceTestState.DataBufferMaxSize); i++) + } + else + { + switch( ComplianceTestState.State ) { - ComplianceTestState.DataBuffer[i] = mcpsIndication->Buffer[i] + 1; + case 4: + ComplianceTestState.State = 1; + break; + case 1: + ComplianceTestState.DataBufferSize = 2; + ComplianceTestState.DataBuffer[0] = ComplianceTestState.DownLinkCounter >> 8; + ComplianceTestState.DataBuffer[1] = ComplianceTestState.DownLinkCounter; + break; } - break; - case 5: /* (viii) */ - { - MlmeReq_t mlmeReq; + } - mlmeReq.Type = MLME_LINK_CHECK; + LmHandlerAppData_t appData = + { + .Buffer = ComplianceTestState.DataBuffer, + .BufferSize = ComplianceTestState.DataBufferSize, + .Port = COMPLIANCE_PORT + }; - LoRaMacMlmeRequest(&mlmeReq); - } - break; - case 6: /* (ix) */ - { - MibRequestConfirm_t mibReq; + // Schedule next transmission + TimerStart( &ComplianceTxNextPacketTimer ); - TimerStop(&ComplianceTxNextPacketTimer); + return LmhpCompliancePackage.OnSendRequest( &appData, ( LmHandlerMsgTypes_t )ComplianceTestState.IsTxConfirmed, NULL, true ); +} - /* Disable TestMode and revert back to normal operation */ - /* Disable compliance test mode and reset the downlink counter. */ - ComplianceTestState.DownLinkCounter = 0; - ComplianceTestState.IsRunning = false; +static void LmhpComplianceOnMcpsIndication( McpsIndication_t* mcpsIndication ) +{ + if( ComplianceTestState.Initialized == false ) + { + return; + } - /* Restore previous ADR seeting */ - mibReq.Type = MIB_ADR; - mibReq.Param.AdrEnable = LmhpComplianceParams->AdrEnabled; - LoRaMacMibSetRequestConfirm(&mibReq); + if( mcpsIndication->RxData == false ) + { + return; + } - /* Enable duty cycle enforcement */ - LoRaMacTestSetDutyCycleOn(LmhpComplianceParams->DutyCycleEnabled); + if ((ComplianceTestState.IsRunning == true) && + (mcpsIndication->AckReceived == 0)) + { + /* Increment the compliance certification protocol downlink counter */ + ComplianceTestState.DownLinkCounter++; + } - /* Restart peripherals */ - if (LmhpComplianceParams->StartPeripherals != NULL) - { - LmhpComplianceParams->StartPeripherals(); - } + if( mcpsIndication->Port != COMPLIANCE_PORT ) + { + return; + } - LmhpCompliancePackage.OnJoinRequest(ACTIVATION_TYPE_OTAA); - } - break; - case 7: /* (x) */ - { - MlmeReq_t mlmeReq; - if (mcpsIndication->BufferSize == 3) + if( ComplianceTestState.IsRunning == false ) + { + // Check compliance test enable command (i) + if( ( mcpsIndication->BufferSize == 4 ) && + ( mcpsIndication->Buffer[0] == 0x01 ) && + ( mcpsIndication->Buffer[1] == 0x01 ) && + ( mcpsIndication->Buffer[2] == 0x01 ) && + ( mcpsIndication->Buffer[3] == 0x01 ) ) { - mlmeReq.Type = MLME_TXCW; - mlmeReq.Req.TxCw.Timeout = (uint16_t)((mcpsIndication->Buffer[1] << 8) | mcpsIndication->Buffer[2]); + MibRequestConfirm_t mibReq; + + // Initialize compliance test mode context + ComplianceTestState.IsTxConfirmed = false; + ComplianceTestState.Port = 224; + ComplianceTestState.DataBufferSize = 2; + ComplianceTestState.DownLinkCounter = 0; + ComplianceTestState.LinkCheck = false; + ComplianceTestState.DemodMargin = 0; + ComplianceTestState.NbGateways = 0; + ComplianceTestState.IsRunning = true; + ComplianceTestState.State = 1; + + // Enable ADR while in compliance test mode + mibReq.Type = MIB_ADR; + mibReq.Param.AdrEnable = true; + LoRaMacMibSetRequestConfirm( &mibReq ); + + // Disable duty cycle enforcement while in compliance test mode + LoRaMacTestSetDutyCycleOn( false ); + + // Stop peripherals + if( LmhpComplianceParams->StopPeripherals != NULL ) + { + LmhpComplianceParams->StopPeripherals( ); + } + // Initialize compliance protocol transmission timer + TimerInit( &ComplianceTxNextPacketTimer, OnComplianceTxNextPacketTimerEvent ); + TimerSetValue( &ComplianceTxNextPacketTimer, COMPLIANCE_TX_DUTYCYCLE ); + + // Confirm compliance test protocol activation + LmhpComplianceTxProcess( ); } - else if (mcpsIndication->BufferSize == 7) + } + else + { + + // Parse compliance test protocol + ComplianceTestState.State = mcpsIndication->Buffer[0]; + switch( ComplianceTestState.State ) { - mlmeReq.Type = MLME_TXCW_1; - mlmeReq.Req.TxCw.Timeout = (uint16_t)((mcpsIndication->Buffer[1] << 8) | mcpsIndication->Buffer[2]); - mlmeReq.Req.TxCw.Frequency = (uint32_t)((mcpsIndication->Buffer[3] << 16) | (mcpsIndication->Buffer[4] << 8) | mcpsIndication->Buffer[5]) * 100; - mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6]; + case 0: // Check compliance test disable command (ii) + { + MibRequestConfirm_t mibReq; + + TimerStop( &ComplianceTxNextPacketTimer ); + + // Disable compliance test mode and reset the downlink counter. + ComplianceTestState.DownLinkCounter = 0; + ComplianceTestState.IsRunning = false; + + // Restore previous ADR seeting + mibReq.Type = MIB_ADR; + mibReq.Param.AdrEnable = LmhpComplianceParams->AdrEnabled; + LoRaMacMibSetRequestConfirm( &mibReq ); + + // Enable duty cycle enforcement + LoRaMacTestSetDutyCycleOn( LmhpComplianceParams->DutyCycleEnabled ); + + // Restart peripherals + if( LmhpComplianceParams->StartPeripherals != NULL ) + { + LmhpComplianceParams->StartPeripherals( ); + } + } + break; + case 1: // (iii, iv) + ComplianceTestState.DataBufferSize = 2; + break; + case 2: // Enable confirmed messages (v) + ComplianceTestState.IsTxConfirmed = true; + ComplianceTestState.State = 1; + break; + case 3: // Disable confirmed messages (vi) + ComplianceTestState.IsTxConfirmed = false; + ComplianceTestState.State = 1; + break; + case 4: // (vii) + ComplianceTestState.DataBufferSize = mcpsIndication->BufferSize; + + ComplianceTestState.DataBuffer[0] = 4; + for( uint8_t i = 1; i < MIN( ComplianceTestState.DataBufferSize, ComplianceTestState.DataBufferMaxSize ); i++ ) + { + ComplianceTestState.DataBuffer[i] = mcpsIndication->Buffer[i] + 1; + } + break; + case 5: // (viii) + { + MlmeReq_t mlmeReq; + + mlmeReq.Type = MLME_LINK_CHECK; + + LoRaMacMlmeRequest( &mlmeReq ); + } + break; + case 6: // (ix) + { + MibRequestConfirm_t mibReq; + + TimerStop(&ComplianceTxNextPacketTimer); + + // Disable TestMode and revert back to normal operation + // Disable compliance test mode and reset the downlink counter. + ComplianceTestState.DownLinkCounter = 0; + ComplianceTestState.IsRunning = false; + + // Restore previous ADR seeting + mibReq.Type = MIB_ADR; + mibReq.Param.AdrEnable = LmhpComplianceParams->AdrEnabled; + LoRaMacMibSetRequestConfirm( &mibReq ); + + // Enable duty cycle enforcement + LoRaMacTestSetDutyCycleOn( LmhpComplianceParams->DutyCycleEnabled ); + + // Restart peripherals + if( LmhpComplianceParams->StartPeripherals != NULL ) + { + LmhpComplianceParams->StartPeripherals( ); + } + + LmhpCompliancePackage.OnJoinRequest( ACTIVATION_TYPE_OTAA ); + } + break; + case 7: // (x) + { + MlmeReq_t mlmeReq; + if( mcpsIndication->BufferSize == 3 ) + { + mlmeReq.Type = MLME_TXCW; + mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] ); + } + else if( mcpsIndication->BufferSize == 7 ) + { + mlmeReq.Type = MLME_TXCW_1; + mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] ); + mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100; + mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6]; + } + LoRaMacMlmeRequest( &mlmeReq ); + ComplianceTestState.State = 1; + } + break; + case 8: // Send DeviceTimeReq + { + MlmeReq_t mlmeReq; + + mlmeReq.Type = MLME_DEVICE_TIME; + + LoRaMacMlmeRequest( &mlmeReq ); + } + break; + case 9: // Switch end device Class + { + MibRequestConfirm_t mibReq; + + mibReq.Type = MIB_DEVICE_CLASS; + // CLASS_A = 0, CLASS_B = 1, CLASS_C = 2 + mibReq.Param.Class = ( DeviceClass_t )mcpsIndication->Buffer[1];; + LoRaMacMibSetRequestConfirm( &mibReq ); + } + break; + case 10: // Send PingSlotInfoReq + { + MlmeReq_t mlmeReq; + + mlmeReq.Type = MLME_PING_SLOT_INFO; + mlmeReq.Req.PingSlotInfo.PingSlot.Value = mcpsIndication->Buffer[1]; + + LoRaMacMlmeRequest( &mlmeReq ); + } + break; + default: + break; } - LoRaMacMlmeRequest(&mlmeReq); - ComplianceTestState.State = 1; - } - break; - case 8: /* Send DeviceTimeReq */ - { - MlmeReq_t mlmeReq; - - mlmeReq.Type = MLME_DEVICE_TIME; - - LoRaMacMlmeRequest(&mlmeReq); - } - break; - case 9: /* Switch end device Class */ - { - MibRequestConfirm_t mibReq; - - mibReq.Type = MIB_DEVICE_CLASS; - /* CLASS_A = 0, CLASS_B = 1, CLASS_C = 2 */ - mibReq.Param.Class = (DeviceClass_t)mcpsIndication->Buffer[1];; - LoRaMacMibSetRequestConfirm(&mibReq); - } - break; - case 10: /* Send PingSlotInfoReq */ - { - MlmeReq_t mlmeReq; - - mlmeReq.Type = MLME_PING_SLOT_INFO; - mlmeReq.Req.PingSlotInfo.PingSlot.Value = mcpsIndication->Buffer[1]; - - LoRaMacMlmeRequest(&mlmeReq); - } - break; - default: - break; } - } } -static void LmhpComplianceProcess(void) +static void LmhpComplianceProcess( void ) { - /* Nothing to process */ + /* Nothing to process */ } -static void OnComplianceTxNextPacketTimerEvent(void *context) +static void OnComplianceTxNextPacketTimerEvent( void* context ) { - LmhpComplianceTxProcess(); + LmhpComplianceTxProcess( ); } diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.h index a3597c36..22be453c 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpCompliance.h @@ -18,75 +18,51 @@ * * \author Miguel Luis ( Semtech ) */ -/** - ****************************************************************************** - * - * Portions COPYRIGHT 2020 STMicroelectronics - * - * @file LmhpCompliance.h - * @author MCD Application Team - * @brief Header for Certification Protocol Handling module - ****************************************************************************** - */ #ifndef __LMHP_COMPLIANCE__ #define __LMHP_COMPLIANCE__ -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ +#include "LoRaMac.h" +#include "LmHandlerTypes.h" #include "LmhPackage.h" -/* Exported defines ----------------------------------------------------------*/ /*! - * Compliance package identifier. - * - * \remark This value must be unique amongst the packages - */ + * Compliance package identifier. + * + * \remark This value must be unique amongst the packages + */ #define PACKAGE_ID_COMPLIANCE 0 -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ /*! - * Compliance test protocol handler parameters - */ + * Compliance test protocol handler parameters + */ typedef struct LmhpComplianceParams_s { - /*! - * Holds the ADR state - */ - bool AdrEnabled; - /*! + /*! + * Holds the ADR state + */ + bool AdrEnabled; + /*! * LoRaWAN ETSI duty cycle control enable/disable * * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes */ - bool DutyCycleEnabled; - /*! - * Stops unnecessary peripherals. - * - * \remark Use for the compliance tests protocol handling in order to - * reduce the power consumption. - */ - void (*StopPeripherals)(void); - /*! - * Starts previously stopped peripherals. - * - * \remark Use for the compliance tests protocol handling in order to - * reduce the power consumption. - */ - void (*StartPeripherals)(void); -} LmhpComplianceParams_t; - -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -LmhPackage_t *LmphCompliancePackageFactory(void); - + bool DutyCycleEnabled; + /*! + * Stops unnecessary peripherals. + * + * \remark Use for the compliance tests protocol handling in order to + * reduce the power consumption. + */ + void ( *StopPeripherals )( void ); + /*! + * Starts previously stopped peripherals. + * + * \remark Use for the compliance tests protocol handling in order to + * reduce the power consumption. + */ + void ( *StartPeripherals )( void ); +}LmhpComplianceParams_t; -#ifdef __cplusplus -} -#endif +LmhPackage_t *LmhpCompliancePackageFactory( void ); -#endif /* __LMHP_COMPLIANCE__ */ +#endif // __LMHP_COMPLIANCE__ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpDataDistribution.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpDataDistribution.c deleted file mode 100644 index dc9c229a..00000000 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpDataDistribution.c +++ /dev/null @@ -1,391 +0,0 @@ -/** - ****************************************************************************** - * @file LmhpDataDistribution.c - * @author MCD Application Team - * @brief Implements the Data Distribution Agent - ****************************************************************************** - * @attention - * - *

    © Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

    - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ -#include "platform.h" -#include "LmhpDataDistribution.h" -#include "LmhpClockSync.h" -#include "LmhpRemoteMcastSetup.h" -#include "LmhpFragmentation.h" -#include "LmhpFirmwareManagement.h" -#include "LmHandler.h" -#include "mw_log_conf.h" -#include "utilities.h" - -#include "flash_if.h" -#include "se_def_metadata.h" - -#define SFU_FWIMG_COMMON_C -#include "sfu_fwimg_regions.h" - -/* Private typedef -----------------------------------------------------------*/ -/*! - * Structure containing values related to the management of multi-images in Flash - */ -typedef struct -{ - uint32_t MaxSizeInBytes; /*!< The maximum allowed size for the FwImage in User Flash (in Bytes) */ - uint32_t DownloadAddr; /*!< The download address for the FwImage in UserFlash */ - uint32_t ImageOffsetInBytes; /*!< Image write starts at this offset */ - uint32_t ExecutionAddr; /*!< The execution address for the FwImage in UserFlash */ -} FwImageFlashTypeDef; - -/* Private define ------------------------------------------------------------*/ -/*! - * Defines the maximum size for the buffer receiving the fragmentation result. - * - * \remark By default FragDecoder.h defines: - * \ref FRAG_MAX_NB 313 - * \ref FRAG_MAX_SIZE 216 - * - * In interop test mode will be - * \ref FRAG_MAX_NB 21 - * \ref FRAG_MAX_SIZE 50 - * - * FileSize = FRAG_MAX_NB * FRAG_MAX_SIZE - * - * If bigger file size is to be received or is fragmented differently - * one must update those parameters. - * - * \remark Memory allocation is done at compile time. Several options have to be foreseen - * in order to optimize the memory. Will depend of the Memory management used - * Could be Dynamic allocation --> malloc method - * Variable Length Array --> VLA method - * pseudo dynamic allocation --> memory pool method - * Other option : - * In place of using the caching memory method we can foreseen to have a direct - * flash memory copy. This solution will depend of the SBSFU constraint - * - */ -#define UNFRAGMENTED_DATA_SIZE ( FRAG_MAX_NB * FRAG_MAX_SIZE ) - -/*! - * Starting offset to add to the first address - */ -#define SFU_IMG_IMAGE_OFFSET ((uint32_t)512U) - -/*! - * Size of header to write in Swap sector to trigger installation - */ -#define INSTALLED_LENGTH ((uint32_t)512U) - -#define SFU_IMG_SWAP_REGION_SIZE ((uint32_t)(SWAP_END - SWAP_START + 1U)) - -#define SFU_IMG_SWAP_REGION_BEGIN_VALUE ((uint32_t)SWAP_START) - -#define SFU_IMG_SLOT_DWL_REGION_BEGIN_VALUE ((uint32_t)SLOT_DWL_1_START) - -#define SFU_IMG_SLOT_DWL_REGION_SIZE ((uint32_t)(SLOT_DWL_1_END - SLOT_DWL_1_START + 1U)) - -/* Private macro -------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/** - * @brief Init `data` buffer of `size` starting at address `addr` - * @param addr Address start index to erase. - * @param size number of bytes. - * @retval status Init operation status [0: Success, -1 Fail] - */ -static uint8_t FragDecoderErase(uint32_t addr, uint32_t size); -/** - * @brief Write `data` buffer of `size` starting at address `addr` - * @param addr Address start index to write to. - * @param data Data buffer to be written. - * @param size Size of data buffer to be written. - * @retval status Write operation status [0: Success, -1 Fail] - */ -static uint8_t FragDecoderWrite(uint32_t addr, uint8_t *data, uint32_t size); - -/** - * @brief Reads `data` buffer of `size` starting at address `addr` - * @param addr Address start index to read from. - * @param data Data buffer to be read. - * @param size Size of data buffer to be read. - * @retval status Read operation status [0: Success, -1 Fail] - */ -static uint8_t FragDecoderRead(uint32_t addr, uint8_t *data, uint32_t size); - -/** - * @brief Callback to get the current progress status of the fragmentation session - * @param fragCounter fragment counter - * @param fragNb number of fragments - * @param fragSize size of fragments - * @param fragNbLost number of lost fragments - * @retval None - */ -static void OnFragProgress(uint16_t fragCounter, uint16_t fragNb, uint8_t fragSize, uint16_t fragNbLost); - -/** - * @brief Callback to notify when the fragmentation session is finished - * @param status status of the fragmentation process - * @param size size of the fragmented data block - * @retval None - */ -static void OnFragDone(int32_t status, uint32_t size); - -#if (INTEROP_TEST_MODE == 0) -/** - * @brief Run FW Update process. - * @param None - * @retval None - */ -static void FwUpdateAgentRun(void); - -/** - * @brief Provide the area descriptor to write a FW image in Flash. - * This function is used by the User Application to know where to store - * a new Firmware Image before asking for its installation. - * @param pArea pointer to area descriptor - * @retval HAL_OK if successful, otherwise HAL_ERROR - */ -static uint32_t FwUpdateAgentGetDownloadAreaInfo(FwImageFlashTypeDef *pArea); - -/** - * @brief Write in Flash the next header image to install. - * This function is used by the User Application to request a Firmware installation (at next reboot). - * @param fw_header FW header of the FW to be installed - * @retval HAL_OK if successful, otherwise HAL_ERROR - */ -static uint32_t FwUpdateAgentInstallAtNextReset(uint8_t *fw_header); -#endif /* INTEROP_TEST_MODE == 0 */ -/* Private variables ---------------------------------------------------------*/ -static LmhpFragmentationParams_t FragmentationParams = -{ - .DecoderCallbacks = - { - .FragDecoderErase = FragDecoderErase, - .FragDecoderWrite = FragDecoderWrite, - .FragDecoderRead = FragDecoderRead, - }, - .OnProgress = OnFragProgress, - .OnDone = OnFragDone -}; - -/* - * Indicates if the file transfer is done - */ -static volatile bool IsFileTransferDone = false; - -#if (INTEROP_TEST_MODE == 1) /*write fragment in RAM - Caching mode*/ -/* - * Un-fragmented data storage. - */ -static uint8_t UnfragmentedData[UNFRAGMENTED_DATA_SIZE]; -#endif /* INTEROP_TEST_MODE == 1 */ - -/* Exported functions ---------------------------------------------------------*/ -LmHandlerErrorStatus_t LmhpDataDistributionInit(void) -{ - if (LmHandlerPackageRegister(PACKAGE_ID_CLOCK_SYNC, NULL) != LORAMAC_HANDLER_SUCCESS) - { - return LORAMAC_HANDLER_ERROR; - } - else if (LmHandlerPackageRegister(PACKAGE_ID_REMOTE_MCAST_SETUP, NULL) != LORAMAC_HANDLER_SUCCESS) - { - return LORAMAC_HANDLER_ERROR; - } - else if (LmHandlerPackageRegister(PACKAGE_ID_FRAGMENTATION, &FragmentationParams) != LORAMAC_HANDLER_SUCCESS) - { - return LORAMAC_HANDLER_ERROR; - } - else if (LmHandlerPackageRegister(PACKAGE_ID_FIRMWARE_MANAGEMENT, NULL) != LORAMAC_HANDLER_SUCCESS) - { - return LORAMAC_HANDLER_ERROR; - } - - return LORAMAC_HANDLER_SUCCESS; -} - -LmHandlerErrorStatus_t LmhpDataDistributionPackageRegister(uint8_t id, LmhPackage_t **package) -{ - if (package == NULL) - { - return LORAMAC_HANDLER_ERROR; - } - switch (id) - { - case PACKAGE_ID_CLOCK_SYNC: - { - *package = LmphClockSyncPackageFactory(); - break; - } - case PACKAGE_ID_REMOTE_MCAST_SETUP: - { - *package = LmhpRemoteMcastSetupPackageFactory(); - break; - } - case PACKAGE_ID_FRAGMENTATION: - { - *package = LmhpFragmentationPackageFactory(); - break; - } - case PACKAGE_ID_FIRMWARE_MANAGEMENT: - { - *package = LmhpFirmwareManagementPackageFactory(); - break; - } - } - - return LORAMAC_HANDLER_SUCCESS; -} - -/* Private functions ---------------------------------------------------------*/ -static uint8_t FragDecoderErase(uint32_t addr, uint32_t size) -{ -#if (INTEROP_TEST_MODE == 1) - for (uint32_t i = 0; i < size; i++) - { - UnfragmentedData[addr + i] = 0xFF; - } -#else /* INTEROP_TEST_MODE == 0 */ - if (FLASH_Erase((void *)(SlotStartAdd[SLOT_DWL_1] + addr), size) != HAL_OK) - { - return -1; - } -#endif /* INTEROP_TEST_MODE */ - return 0; /* Success */ -} - -static uint8_t FragDecoderWrite(uint32_t addr, uint8_t *data, uint32_t size) -{ - if (size >= UNFRAGMENTED_DATA_SIZE) - { - return (uint8_t) - 1; /* Fail */ - } -#if (INTEROP_TEST_MODE == 1) /*write fragment in RAM - Caching mode*/ - for (uint32_t i = 0; i < size; i++) - { - UnfragmentedData[addr + i] = data[i]; - } -#else /* INTEROP_TEST_MODE == 0 */ - if (FLASH_Write(SlotStartAdd[SLOT_DWL_1] + addr, data, size) != HAL_OK) - { - return -1; - } -#endif /* INTEROP_TEST_MODE */ - - return 0; /* Success */ -} - -static uint8_t FragDecoderRead(uint32_t addr, uint8_t *data, uint32_t size) -{ - if (size >= UNFRAGMENTED_DATA_SIZE) - { - return (uint8_t) - 1; /* Fail */ - } - -#if (INTEROP_TEST_MODE == 1) /*Read fragment in RAM - Caching mode*/ - for (uint32_t i = 0; i < size; i++) - { - data[i] = UnfragmentedData[addr + i]; - } -#else /* INTEROP_TEST_MODE == 0 */ - if (FLASH_Read((void *)(SlotStartAdd[SLOT_DWL_1] + addr), data, size) != HAL_OK) - { - return -1; - } -#endif /* INTEROP_TEST_MODE */ - - return 0; /* Success */ -} - -static void OnFragProgress(uint16_t fragCounter, uint16_t fragNb, uint8_t fragSize, uint16_t fragNbLost) -{ -#if (INTEROP_TEST_MODE == 1) - /* BSP_LED_On(LED_BLUE); */ - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET); -#endif /* INTEROP_TEST_MODE == 1 */ - - MW_LOG(TS_OFF, VLEVEL_M, "\r\n....... FRAG_DECODER in Progress .......\r\n"); - MW_LOG(TS_OFF, VLEVEL_M, "RECEIVED : %5d / %5d Fragments\r\n", fragCounter, fragNb); - MW_LOG(TS_OFF, VLEVEL_M, " %5d / %5d Bytes\r\n", fragCounter * fragSize, fragNb * fragSize); - MW_LOG(TS_OFF, VLEVEL_M, "LOST : %7d Fragments\r\n\r\n", fragNbLost); -} - -static void OnFragDone(int32_t status, uint32_t size) -{ - IsFileTransferDone = true; -#if (INTEROP_TEST_MODE == 0) - /* Do a request to Run the Secure boot - The file is already in flash */ - FwUpdateAgentRun(); -#else - /* BSP_LED_Off(LED_BLUE); */ - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET); -#endif /* INTEROP_TEST_MODE == 1 */ - MW_LOG(TS_OFF, VLEVEL_M, "\r\n....... FRAG_DECODER Finished .......\r\n"); - MW_LOG(TS_OFF, VLEVEL_M, "STATUS : %d\r\n", status); -} - -#if (INTEROP_TEST_MODE == 0) -static void FwUpdateAgentRun(void) -{ - HAL_StatusTypeDef ret = HAL_ERROR; - uint8_t fw_header_dwl_slot[SE_FW_HEADER_TOT_LEN]; - FwImageFlashTypeDef fw_image_dwl_area; - - /* Get Info about the download area */ - if (FwUpdateAgentGetDownloadAreaInfo(&fw_image_dwl_area) != HAL_ERROR) - { - /* Read header in slot 1 */ - ret = FLASH_Read(fw_header_dwl_slot, (void *) fw_image_dwl_area.DownloadAddr, SE_FW_HEADER_TOT_LEN); - - /* Ask for installation at next reset */ - (void)FwUpdateAgentInstallAtNextReset((uint8_t *) fw_header_dwl_slot); - - /* System Reboot*/ - NVIC_SystemReset(); - } - if (ret != HAL_OK) - { - MW_LOG(TS_OFF, VLEVEL_M, " -- Operation Failed \r\n"); - } -} - -static uint32_t FwUpdateAgentGetDownloadAreaInfo(FwImageFlashTypeDef *pArea) -{ - uint32_t ret; - if (pArea != NULL) - { - pArea->DownloadAddr = SFU_IMG_SLOT_DWL_REGION_BEGIN_VALUE; - pArea->MaxSizeInBytes = (uint32_t)SFU_IMG_SLOT_DWL_REGION_SIZE; - pArea->ImageOffsetInBytes = SFU_IMG_IMAGE_OFFSET; - ret = HAL_OK; - } - else - { - ret = HAL_ERROR; - } - return ret; -} - -static uint32_t FwUpdateAgentInstallAtNextReset(uint8_t *pfw_header) -{ - uint32_t ret = HAL_OK; - - if (pfw_header == NULL) - { - return HAL_ERROR; - } - - ret = FLASH_Erase((void *) SFU_IMG_SWAP_REGION_BEGIN_VALUE, SFU_IMG_IMAGE_OFFSET); - if (ret == HAL_OK) - { - ret = FLASH_Write(SFU_IMG_SWAP_REGION_BEGIN_VALUE, pfw_header, SE_FW_HEADER_TOT_LEN); - } - return ret; -} -#endif /* INTEROP_TEST_MODE == 0 */ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpDataDistribution.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpDataDistribution.h deleted file mode 100644 index 9d259e3c..00000000 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpDataDistribution.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - ****************************************************************************** - * @file LmhpDataDistribution.h - * @author MCD Application Team - * @brief Function prototypes for LoRaMac Data distribution agent - ****************************************************************************** - * @attention - * - *

    © Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

    - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ -#ifndef __LMHP_DATA_DISTRIBUTION_H__ -#define __LMHP_DATA_DISTRIBUTION_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "LmhPackage.h" - -/* Exported defines ----------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -LmHandlerErrorStatus_t LmhpDataDistributionInit(void); - -LmHandlerErrorStatus_t LmhpDataDistributionPackageRegister(uint8_t id, LmhPackage_t **package); - -#ifdef __cplusplus -} -#endif - -#endif /* __LMHP_DATA_DISTRIBUTION_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFirmwareManagement.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFirmwareManagement.c index 70e48a58..03b04bf1 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFirmwareManagement.c +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFirmwareManagement.c @@ -17,6 +17,7 @@ ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ +#include "platform.h" #include "LmHandler.h" #include "LmhpFirmwareManagement.h" #include "mw_log_conf.h" /* needed for MW_LOG */ @@ -131,6 +132,7 @@ static LmhPackage_t LmhpFirmwareManagementPackage = .OnJoinRequest = NULL, /* To be initialized by LmHandler */ .OnSendRequest = NULL, /* To be initialized by LmHandler */ .OnDeviceTimeRequest = NULL, /* To be initialized by LmHandler */ + .OnPackageProcessEvent = NULL, /* To be initialized by LmHandler */ }; /*! diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.c index 6d06f9e7..6c7b3107 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.c +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.c @@ -1,24 +1,24 @@ /*! - * \file LmhpFragmentation.c - * - * \brief Implements the LoRa-Alliance fragmented data block transport package - * Specification: https://lora-alliance.org/sites/default/files/2018-09/fragmented_data_block_transport_v1.0.0.pdf - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2013-2018 Semtech - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - */ + * \file LmhpFragmentation.c + * + * \brief Implements the LoRa-Alliance fragmented data block transport package + * Specification: https://lora-alliance.org/sites/default/files/2018-09/fragmented_data_block_transport_v1.0.0.pdf + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2018 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + */ /** ****************************************************************************** * @@ -26,126 +26,88 @@ * * @file LmhpFragmentation.c * @author MCD Application Team - * @brief Fragmentation Data Block Transport Package definition + * @brief Implements the LoRa-Alliance fragmented data block transport package ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "LmHandler.h" #include "LmhpFragmentation.h" +#include "FragDecoder.h" +#include "frag_decoder_if.h" #include "utilities.h" -/* Private typedef -----------------------------------------------------------*/ -/* Fragmentation Tx delay state */ +/*! + * LoRaWAN Application Layer Fragmented Data Block Transport Specification + */ +#define FRAGMENTATION_PORT 201 + +#define FRAGMENTATION_ID 3 +#define FRAGMENTATION_VERSION 1 + +#define FRAGMENTATION_MAX_SESSIONS 4 + +// Fragmentation Tx delay state typedef enum LmhpFragmentationTxDelayStates_e { - /* Tx delay in idle state */ - FRAGMENTATION_TX_DELAY_STATE_IDLE, - /* Tx delay to be started */ - FRAGMENTATION_TX_DELAY_STATE_START, - /* Tx is in pending */ - FRAGMENTATION_TX_DELAY_STATE_PENDING, -} LmhpFragmentationTxDelayStates_t; + // Tx delay in idle state. + FRAGMENTATION_TX_DELAY_STATE_IDLE, + // Tx delay to be started. + FRAGMENTATION_TX_DELAY_STATE_START, + // Tx is in pending + FRAGMENTATION_TX_DELAY_STATE_PENDING, +}LmhpFragmentationTxDelayStates_t; /*! * Package current context */ typedef struct LmhpFragmentationState_s { - bool Initialized; - bool IsRunning; - LmhpFragmentationTxDelayStates_t TxDelayState; - uint8_t DataBufferMaxSize; - uint8_t *DataBuffer; - uint8_t *file; -} LmhpFragmentationState_t; + bool Initialized; + bool IsRunning; + LmhpFragmentationTxDelayStates_t TxDelayState; + uint8_t DataBufferMaxSize; + uint8_t *DataBuffer; + uint8_t *file; +}LmhpFragmentationState_t; typedef enum LmhpFragmentationMoteCmd_e { - FRAGMENTATION_PKG_VERSION_ANS = 0x00, - FRAGMENTATION_FRAG_STATUS_ANS = 0x01, - FRAGMENTATION_FRAG_SESSION_SETUP_ANS = 0x02, - FRAGMENTATION_FRAG_SESSION_DELETE_ANS = 0x03, -} LmhpFragmentationMoteCmd_t; + FRAGMENTATION_PKG_VERSION_ANS = 0x00, + FRAGMENTATION_FRAG_STATUS_ANS = 0x01, + FRAGMENTATION_FRAG_SESSION_SETUP_ANS = 0x02, + FRAGMENTATION_FRAG_SESSION_DELETE_ANS = 0x03, +}LmhpFragmentationMoteCmd_t; typedef enum LmhpFragmentationSrvCmd_e { - FRAGMENTATION_PKG_VERSION_REQ = 0x00, - FRAGMENTATION_FRAG_STATUS_REQ = 0x01, - FRAGMENTATION_FRAG_SESSION_SETUP_REQ = 0x02, - FRAGMENTATION_FRAG_SESSION_DELETE_REQ = 0x03, - FRAGMENTATION_DATA_FRAGMENT = 0x08, -} LmhpFragmentationSrvCmd_t; - -typedef struct FragGroupData_s -{ - bool IsActive; - union - { - uint8_t Value; - struct - { - uint8_t McGroupBitMask: 4; - uint8_t FragIndex: 2; - uint8_t RFU: 2; - } Fields; - } FragSession; - uint16_t FragNb; - uint8_t FragSize; - union - { - uint8_t Value; - struct - { - uint8_t BlockAckDelay: 3; - uint8_t FragAlgo: 3; - uint8_t RFU: 2; - } Fields; - } Control; - uint8_t Padding; - uint32_t Descriptor; -} FragGroupData_t; - -typedef struct FragSessionData_s -{ - FragGroupData_t FragGroupData; - FragDecoderStatus_t FragDecoderStatus; - int32_t FragDecoderProcessStatus; -} FragSessionData_t; - -/* Private define ------------------------------------------------------------*/ -/*! - * LoRaWAN Application Layer Fragmented Data Block Transport Specification - */ -#define FRAGMENTATION_PORT 201 + FRAGMENTATION_PKG_VERSION_REQ = 0x00, + FRAGMENTATION_FRAG_STATUS_REQ = 0x01, + FRAGMENTATION_FRAG_SESSION_SETUP_REQ = 0x02, + FRAGMENTATION_FRAG_SESSION_DELETE_REQ = 0x03, + FRAGMENTATION_DATA_FRAGMENT = 0x08, +}LmhpFragmentationSrvCmd_t; -#define FRAGMENTATION_ID 3 -#define FRAGMENTATION_VERSION 1 - -#define FRAGMENTATION_MAX_SESSIONS 4 - -/* Private macro -------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ /*! - * \brief Callback function for Fragment delay timer. + * LoRaWAN fragmented data block transport handler parameters */ -static void OnFragmentTxDelay(void *context); +static LmhpFragmentationParams_t* LmhpFragmentationParams; /*! * Initializes the package with provided parameters * - * \param [in] params Pointer to the package parameters - * \param [in] dataBuffer Pointer to main application buffer - * \param [in] dataBufferMaxSize Main application buffer maximum size + * \param [IN] params Pointer to the package parameters + * \param [IN] dataBuffer Pointer to main application buffer + * \param [IN] dataBufferMaxSize Main application buffer maximum size */ -static void LmhpFragmentationInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize); +static void LmhpFragmentationInit( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ); /*! -* Returns the current package initialization status. -* -* \retval status Package initialization status -* [true: Initialized, false: Not initialized] -*/ -static bool LmhpFragmentationIsInitialized(void); + * Returns the current package initialization status. + * + * \retval status Package initialization status + * [true: Initialized, false: Not initialized] + */ +static bool LmhpFragmentationIsInitialized( void ); /*! * Returns the package operation status. @@ -153,387 +115,437 @@ static bool LmhpFragmentationIsInitialized(void); * \retval status Package operation status * [true: Running, false: Not running] */ -static bool LmhpFragmentationIsRunning(void); +static bool LmhpFragmentationIsRunning( void ); /*! * Processes the internal package events. */ -static void LmhpFragmentationProcess(void); +static void LmhpFragmentationProcess( void ); /*! * Processes the MCPS Indication * - * \param [in] mcpsIndication MCPS indication primitive data + * \param [IN] mcpsIndication MCPS indication primitive data */ -static void LmhpFragmentationOnMcpsIndication(McpsIndication_t *mcpsIndication); +static void LmhpFragmentationOnMcpsIndication( McpsIndication_t *mcpsIndication ); -/* Private variables ---------------------------------------------------------*/ /*! - * LoRaWAN fragmented data block transport handler parameters + * \brief Callback function for Fragment delay timer. */ -static LmhpFragmentationParams_t *LmhpFragmentationParams; +static void OnFragmentTxDelay(void *context); static LmhpFragmentationState_t LmhpFragmentationState = { - .Initialized = false, - .IsRunning = false, - .TxDelayState = FRAGMENTATION_TX_DELAY_STATE_IDLE, + .Initialized = false, + .IsRunning = false, + .TxDelayState = FRAGMENTATION_TX_DELAY_STATE_IDLE, }; +typedef struct FragGroupData_s +{ + bool IsActive; + union + { + uint8_t Value; + struct + { + uint8_t McGroupBitMask: 4; + uint8_t FragIndex: 2; + uint8_t RFU: 2; + }Fields; + }FragSession; + uint16_t FragNb; + uint8_t FragSize; + union + { + uint8_t Value; + struct + { + uint8_t BlockAckDelay: 3; + uint8_t FragAlgo: 3; + uint8_t RFU: 2; + }Fields; + }Control; + uint8_t Padding; + uint32_t Descriptor; +}FragGroupData_t; + +typedef struct FragSessionData_s +{ + FragGroupData_t FragGroupData; + FragDecoderStatus_t FragDecoderStatus; + int32_t FragDecoderProcessStatus; +}FragSessionData_t; + static FragSessionData_t FragSessionData[FRAGMENTATION_MAX_SESSIONS]; -/* Answer struct for the commands. */ +// Answer struct for the commands. LmHandlerAppData_t DelayedReplyAppData; static LmhPackage_t LmhpFragmentationPackage = { - .Port = FRAGMENTATION_PORT, - .Init = LmhpFragmentationInit, - .IsInitialized = LmhpFragmentationIsInitialized, - .IsRunning = LmhpFragmentationIsRunning, - .Process = LmhpFragmentationProcess, - .OnMcpsConfirmProcess = NULL, /* Not used in this package */ - .OnMcpsIndicationProcess = LmhpFragmentationOnMcpsIndication, - .OnMlmeConfirmProcess = NULL, /* Not used in this package */ - .OnJoinRequest = NULL, /* To be initialized by LmHandler */ - .OnSendRequest = NULL, /* To be initialized by LmHandler */ - .OnDeviceTimeRequest = NULL, /* To be initialized by LmHandler */ + .Port = FRAGMENTATION_PORT, + .Init = LmhpFragmentationInit, + .IsInitialized = LmhpFragmentationIsInitialized, + .IsRunning = LmhpFragmentationIsRunning, + .Process = LmhpFragmentationProcess, + .OnMcpsConfirmProcess = NULL, // Not used in this package + .OnMcpsIndicationProcess = LmhpFragmentationOnMcpsIndication, + .OnMlmeConfirmProcess = NULL, // Not used in this package + .OnJoinRequest = NULL, // To be initialized by LmHandler + .OnSendRequest = NULL, // To be initialized by LmHandler + .OnDeviceTimeRequest = NULL, // To be initialized by LmHandler + .OnSysTimeUpdate = NULL, // To be initialized by LmHandler + .OnPackageProcessEvent = NULL, // To be initialized by LmHandler }; -/* Delay value. */ +// Delay value. static uint32_t TxDelayTime; -/* Fragment Delay Timer struct */ +// Fragment Delay Timer struct static TimerEvent_t FragmentTxDelayTimer; -/* Exported functions ---------------------------------------------------------*/ -LmhPackage_t *LmhpFragmentationPackageFactory(void) -{ - return &LmhpFragmentationPackage; -} -/* Private functions ---------------------------------------------------------*/ -static void OnFragmentTxDelay(void *context) +/*! + * \brief Callback function for Fragment delay timer. + */ +static void OnFragmentTxDelay( void* context ) { - /* Stop the timer. */ - TimerStop(&FragmentTxDelayTimer); - /* Set the state. */ - LmhpFragmentationState.TxDelayState = FRAGMENTATION_TX_DELAY_STATE_PENDING; + // Stop the timer. + TimerStop( &FragmentTxDelayTimer ); + // Set the state. + LmhpFragmentationState.TxDelayState = FRAGMENTATION_TX_DELAY_STATE_PENDING; + LmhpFragmentationPackage.OnPackageProcessEvent(); } -static void LmhpFragmentationInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize) +LmhPackage_t *LmhpFragmentationPackageFactory( void ) { - if ((params != NULL) && (dataBuffer != NULL)) - { - LmhpFragmentationParams = (LmhpFragmentationParams_t *)params; - LmhpFragmentationState.DataBuffer = dataBuffer; - LmhpFragmentationState.DataBufferMaxSize = dataBufferMaxSize; - LmhpFragmentationState.Initialized = true; - LmhpFragmentationState.IsRunning = true; - /* Initialize Fragmentation delay time. */ - TxDelayTime = 0; - /* Initialize Fragmentation delay timer. */ - TimerInit(&FragmentTxDelayTimer, OnFragmentTxDelay); - } - else - { - LmhpFragmentationParams = NULL; - LmhpFragmentationState.IsRunning = false; - LmhpFragmentationState.Initialized = false; - } - - /* initialize the global fragmentation session buffer */ - UTIL_MEM_set_8(FragSessionData, 0, sizeof(FragSessionData)); + return &LmhpFragmentationPackage; } -static bool LmhpFragmentationIsInitialized(void) +uint8_t LmhpFragmentationGetPackageVersion(void) { - return LmhpFragmentationState.Initialized; + return (uint8_t)FRAGMENTATION_VERSION; } -static bool LmhpFragmentationIsRunning(void) +static void LmhpFragmentationInit( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ) { - if (LmhpFragmentationState.Initialized == false) - { - return false; - } + if( ( params != NULL ) && ( dataBuffer != NULL ) ) + { + LmhpFragmentationParams = ( LmhpFragmentationParams_t* )params; + LmhpFragmentationState.DataBuffer = dataBuffer; + LmhpFragmentationState.DataBufferMaxSize = dataBufferMaxSize; + LmhpFragmentationState.Initialized = true; + LmhpFragmentationState.IsRunning = true; + // Initialize Fragmentation delay time. + TxDelayTime = 0; + // Initialize Fragmentation delay timer. + TimerInit( &FragmentTxDelayTimer, OnFragmentTxDelay ); + } + else + { + LmhpFragmentationParams = NULL; + LmhpFragmentationState.IsRunning = false; + LmhpFragmentationState.Initialized = false; + } - return LmhpFragmentationState.IsRunning; + /* initialize the global fragmentation session buffer */ + UTIL_MEM_set_8( FragSessionData, 0, sizeof(FragSessionData) ); } -static void LmhpFragmentationProcess(void) +static bool LmhpFragmentationIsInitialized( void ) { - LmhpFragmentationTxDelayStates_t delayTimerState; - TimerTime_t nextTxIn = 0; - - CRITICAL_SECTION_BEGIN(); - delayTimerState = LmhpFragmentationState.TxDelayState; - CRITICAL_SECTION_END(); - - switch (delayTimerState) - { - case FRAGMENTATION_TX_DELAY_STATE_START: - /* Set the timer with the initially calculated Delay value. */ - TimerSetValue(&FragmentTxDelayTimer, TxDelayTime); - /* Start the timer. */ - TimerStart(&FragmentTxDelayTimer); - break; - case FRAGMENTATION_TX_DELAY_STATE_PENDING: - /* Send the reply. */ - if (LmhpFragmentationPackage.OnSendRequest(&DelayedReplyAppData, LORAMAC_HANDLER_UNCONFIRMED_MSG, &nextTxIn, - true) == LORAMAC_HANDLER_SUCCESS) - { - LmhpFragmentationState.TxDelayState = FRAGMENTATION_TX_DELAY_STATE_IDLE; - } - break; - case FRAGMENTATION_TX_DELAY_STATE_IDLE: - /* Intentional fall through */ - default: - /* Nothing to do. */ - break; - } + return LmhpFragmentationState.Initialized; } -static void LmhpFragmentationOnMcpsIndication(McpsIndication_t *mcpsIndication) +static bool LmhpFragmentationIsRunning( void ) { - uint8_t cmdIndex = 0; - uint8_t dataBufferIndex = 0; - bool isAnswerDelayed = false; - /* Co-efficient used to calculate delay. */ - uint8_t blockAckDelay = 0; - - while (cmdIndex < mcpsIndication->BufferSize) - { - switch (mcpsIndication->Buffer[cmdIndex++]) + if( LmhpFragmentationState.Initialized == false ) { - case FRAGMENTATION_PKG_VERSION_REQ: - { - if (mcpsIndication->Multicast == 1) - { - /* Multicast channel. Don't process command. */ - break; - } - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_PKG_VERSION_ANS; - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_ID; - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_VERSION; - break; - } - case FRAGMENTATION_FRAG_STATUS_REQ: - { - uint8_t fragIndex = mcpsIndication->Buffer[cmdIndex++]; - uint8_t participants = fragIndex & 0x01; - - fragIndex >>= 1; - FragSessionData[fragIndex].FragDecoderStatus = FragDecoderGetStatus(); - - if ((participants == 1) || - ((participants == 0) && (FragSessionData[fragIndex].FragDecoderStatus.FragNbLost > 0))) - { - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_FRAG_STATUS_ANS; - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = (fragIndex << 14) | - ((FragSessionData[fragIndex].FragDecoderStatus.FragNbRx >> 8) & 0x3F); - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FragSessionData[fragIndex].FragDecoderStatus.FragNbRx & 0xFF; - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FragSessionData[fragIndex].FragDecoderStatus.FragNbLost; - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FragSessionData[fragIndex].FragDecoderStatus.MatrixError & 0x01; - - /* Fetch the co-efficient value required to calculate delay of that respective session. */ - blockAckDelay = FragSessionData[fragIndex].FragGroupData.Control.Fields.BlockAckDelay; - isAnswerDelayed = true; - } - break; - } - case FRAGMENTATION_FRAG_SESSION_SETUP_REQ: - { - if (mcpsIndication->Multicast == 1) - { - /* Multicast channel. Don't process command. */ - break; - } - FragSessionData_t fragSessionData; - uint8_t status = 0x00; - - fragSessionData.FragGroupData.FragSession.Value = mcpsIndication->Buffer[cmdIndex++]; - - fragSessionData.FragGroupData.FragNb = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x00FF; - fragSessionData.FragGroupData.FragNb |= (mcpsIndication->Buffer[cmdIndex++] << 8) & 0xFF00; - - fragSessionData.FragGroupData.FragSize = mcpsIndication->Buffer[cmdIndex++]; + return false; + } - fragSessionData.FragGroupData.Control.Value = mcpsIndication->Buffer[cmdIndex++]; + return LmhpFragmentationState.IsRunning; +} - fragSessionData.FragGroupData.Padding = mcpsIndication->Buffer[cmdIndex++]; +static void LmhpFragmentationProcess( void ) +{ + LmhpFragmentationTxDelayStates_t delayTimerState; - fragSessionData.FragGroupData.Descriptor = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x000000FF; - fragSessionData.FragGroupData.Descriptor += (mcpsIndication->Buffer[cmdIndex++] << 8) & 0x0000FF00; - fragSessionData.FragGroupData.Descriptor += (mcpsIndication->Buffer[cmdIndex++] << 16) & 0x00FF0000; - fragSessionData.FragGroupData.Descriptor += (mcpsIndication->Buffer[cmdIndex++] << 24) & 0xFF000000; + CRITICAL_SECTION_BEGIN( ); + delayTimerState = LmhpFragmentationState.TxDelayState; + CRITICAL_SECTION_END( ); - if (fragSessionData.FragGroupData.Control.Fields.FragAlgo > 0) - { - status |= 0x01; /* Encoding unsupported */ - } - - if ((fragSessionData.FragGroupData.FragNb * fragSessionData.FragGroupData.FragSize) > FragDecoderGetMaxFileSize()) - { - status |= 0x02; /* Not enough Memory */ - } - status |= (fragSessionData.FragGroupData.FragSession.Fields.FragIndex << 6) & 0xC0; - if (fragSessionData.FragGroupData.FragSession.Fields.FragIndex >= FRAGMENTATION_MAX_SESSIONS) - { - status |= 0x04; /* FragSession index not supported */ - } + switch( delayTimerState ) + { + case FRAGMENTATION_TX_DELAY_STATE_START: + // Set the timer with the initially calculated Delay value. + TimerSetValue( &FragmentTxDelayTimer, TxDelayTime ); + // Start the timer. + TimerStart( &FragmentTxDelayTimer ); + break; + case FRAGMENTATION_TX_DELAY_STATE_PENDING: + // Send the reply. + if (LORAMAC_HANDLER_SUCCESS == LmhpFragmentationPackage.OnSendRequest( &DelayedReplyAppData, + LORAMAC_HANDLER_UNCONFIRMED_MSG, + NULL, + true ) ) + { + LmhpFragmentationState.TxDelayState = FRAGMENTATION_TX_DELAY_STATE_IDLE; + } + break; + case FRAGMENTATION_TX_DELAY_STATE_IDLE: + // Intentional fall through + default: + // Nothing to do. + break; + } +} - /* Descriptor is not really defined in the specification */ - /* Not clear how to handle this. */ - /* Currently the descriptor is always correct */ - if (fragSessionData.FragGroupData.Descriptor != 0x01020304) - { - /* status |= 0x08; // Wrong Descriptor */ - } +static void LmhpFragmentationOnMcpsIndication( McpsIndication_t *mcpsIndication ) +{ + uint8_t cmdIndex = 0; + uint8_t dataBufferIndex = 0; + bool isAnswerDelayed = false; + // Answer struct for the commands. + LmHandlerAppData_t cmdReplyAppData; + // Co-efficient used to calculate delay. + uint8_t blockAckDelay = 0; + + if( mcpsIndication->Port != FRAGMENTATION_PORT ) + { + return; + } - if ((status & 0x0F) == 0) - { - /* The FragSessionSetup is accepted */ - fragSessionData.FragGroupData.IsActive = true; - fragSessionData.FragDecoderProcessStatus = FRAG_SESSION_ONGOING; - FragSessionData[fragSessionData.FragGroupData.FragSession.Fields.FragIndex] = fragSessionData; - FragDecoderInit(fragSessionData.FragGroupData.FragNb, - fragSessionData.FragGroupData.FragSize, - &LmhpFragmentationParams->DecoderCallbacks); - } - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_FRAG_SESSION_SETUP_ANS; - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = status; - isAnswerDelayed = false; - break; - } - case FRAGMENTATION_FRAG_SESSION_DELETE_REQ: - { - if (mcpsIndication->Multicast == 1) + while( cmdIndex < mcpsIndication->BufferSize ) + { + switch( mcpsIndication->Buffer[cmdIndex++] ) { - /* Multicast channel. Don't process command. */ - break; + case FRAGMENTATION_PKG_VERSION_REQ: + { + if( mcpsIndication->Multicast == 1 ) + { + // Multicast channel. Don't process command. + break; + } + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_PKG_VERSION_ANS; + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_ID; + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_VERSION; + break; + } + case FRAGMENTATION_FRAG_STATUS_REQ: + { + uint8_t fragIndex = mcpsIndication->Buffer[cmdIndex++]; + uint8_t participants = fragIndex & 0x01; + + fragIndex = (fragIndex >> 1 ) & 0x03; + FragSessionData[fragIndex].FragDecoderStatus = FragDecoderGetStatus( ); + + if( ( participants == 1 ) || + ( ( participants == 0 ) && ( FragSessionData[fragIndex].FragDecoderStatus.FragNbLost > 0 ) ) ) + { + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_FRAG_STATUS_ANS; + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FragSessionData[fragIndex].FragDecoderStatus.FragNbRx & 0xFF; + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = ( fragIndex << 6 ) | + ( ( FragSessionData[fragIndex].FragDecoderStatus.FragNbRx >> 8 ) & 0x3F ); + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FragSessionData[fragIndex].FragDecoderStatus.FragNbLost; + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FragSessionData[fragIndex].FragDecoderStatus.MatrixError & 0x01; + + // Fetch the co-efficient value required to calculate delay of that respective session. + blockAckDelay = FragSessionData[fragIndex].FragGroupData.Control.Fields.BlockAckDelay; + isAnswerDelayed = true; + } + break; + } + case FRAGMENTATION_FRAG_SESSION_SETUP_REQ: + { + if( mcpsIndication->Multicast == 1 ) + { + // Multicast channel. Don't process command. + break; + } + FragSessionData_t fragSessionData; + uint8_t status = 0x00; + + fragSessionData.FragGroupData.FragSession.Value = mcpsIndication->Buffer[cmdIndex++]; + + fragSessionData.FragGroupData.FragNb = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x00FF; + fragSessionData.FragGroupData.FragNb |= ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0xFF00; + + fragSessionData.FragGroupData.FragSize = mcpsIndication->Buffer[cmdIndex++]; + + fragSessionData.FragGroupData.Control.Value = mcpsIndication->Buffer[cmdIndex++]; + + fragSessionData.FragGroupData.Padding = mcpsIndication->Buffer[cmdIndex++]; + + fragSessionData.FragGroupData.Descriptor = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF; + fragSessionData.FragGroupData.Descriptor += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00; + fragSessionData.FragGroupData.Descriptor += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000; + fragSessionData.FragGroupData.Descriptor += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000; + + if( fragSessionData.FragGroupData.Control.Fields.FragAlgo > 0 ) + { + status |= 0x01; // Encoding unsupported + } + + if( ( fragSessionData.FragGroupData.FragNb > FRAG_MAX_NB ) || + ( fragSessionData.FragGroupData.FragSize > FRAG_MAX_SIZE ) || + ( ( fragSessionData.FragGroupData.FragNb * fragSessionData.FragGroupData.FragSize ) > FragDecoderGetMaxFileSize( ) ) ) + { + status |= 0x02; // Not enough Memory + } + status |= ( fragSessionData.FragGroupData.FragSession.Fields.FragIndex << 6 ) & 0xC0; + if( fragSessionData.FragGroupData.FragSession.Fields.FragIndex >= FRAGMENTATION_MAX_SESSIONS ) + { + status |= 0x04; // FragSession index not supported + } + + // Descriptor is not really defined in the specification + // Not clear how to handle this. + // Currently the descriptor is always correct + if( fragSessionData.FragGroupData.Descriptor != 0x01020304 ) + { + //status |= 0x08; // Wrong Descriptor + } + + if( ( status & 0x0F ) == 0 ) + { + // The FragSessionSetup is accepted + fragSessionData.FragGroupData.IsActive = true; + fragSessionData.FragDecoderProcessStatus = FRAG_SESSION_ONGOING; + FragSessionData[fragSessionData.FragGroupData.FragSession.Fields.FragIndex] = fragSessionData; + FragDecoderInit( fragSessionData.FragGroupData.FragNb, + fragSessionData.FragGroupData.FragSize, + &LmhpFragmentationParams->DecoderCallbacks ); + } + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_FRAG_SESSION_SETUP_ANS; + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = status; + isAnswerDelayed = false; + break; + } + case FRAGMENTATION_FRAG_SESSION_DELETE_REQ: + { + if( mcpsIndication->Multicast == 1 ) + { + // Multicast channel. Don't process command. + break; + } + uint8_t status = 0x00; + uint8_t id = mcpsIndication->Buffer[cmdIndex++] & 0x03; + + status |= id; + if( ( id >= FRAGMENTATION_MAX_SESSIONS ) || ( FragSessionData[id].FragGroupData.IsActive == false ) ) + { + status |= 0x04; // Session does not exist + } + else + { + // Delete session + FragSessionData[id].FragGroupData.IsActive = false; + } + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_FRAG_SESSION_DELETE_ANS; + LmhpFragmentationState.DataBuffer[dataBufferIndex++] = status; + isAnswerDelayed = false; + break; + } + case FRAGMENTATION_DATA_FRAGMENT: + { + uint8_t fragIndex = 0; + uint16_t fragCounter = 0; + + fragCounter = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x00FF; + fragCounter |= ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0xFF00; + + fragIndex = ( fragCounter >> 14 ) & 0x03; + fragCounter &= 0x3FFF; + if (FragSessionData[fragIndex].FragGroupData.IsActive == false) + { + cmdIndex = mcpsIndication->BufferSize; + break; + } + if( mcpsIndication->Multicast == 1 ) + { + // Message received on a multicast address + // Check McGroupBitMask + uint8_t groupId = LoRaMacMcChannelGetGroupId( mcpsIndication->DevAddress ); + if( ( groupId == 0xFF ) || + ( ( FragSessionData[fragIndex].FragGroupData.FragSession.Fields.McGroupBitMask & ( 1 << groupId ) ) == 0 ) ) + { + // Ignore message + cmdIndex = mcpsIndication->BufferSize; + break; + } + } + + if (FragSessionData[fragIndex].FragDecoderProcessStatus == FRAG_SESSION_ONGOING) + { + FragSessionData[fragIndex].FragDecoderProcessStatus = FragDecoderProcess( fragCounter, &mcpsIndication->Buffer[cmdIndex] ); + FragSessionData[fragIndex].FragDecoderStatus = FragDecoderGetStatus( ); + if( LmhpFragmentationParams->OnProgress != NULL ) + { + LmhpFragmentationParams->OnProgress( FragSessionData[fragIndex].FragDecoderStatus.FragNbRx, + FragSessionData[fragIndex].FragGroupData.FragNb, + FragSessionData[fragIndex].FragGroupData.FragSize, + FragSessionData[fragIndex].FragDecoderStatus.FragNbLost ); + } + + if( FragSessionData[fragIndex].FragDecoderProcessStatus >= 0 ) + { + // Fragmentation successfully done + if( LmhpFragmentationParams->OnDone != NULL ) + { + LmhpFragmentationParams->OnDone( FragSessionData[fragIndex].FragDecoderProcessStatus, + ( FragSessionData[fragIndex].FragGroupData.FragNb * FragSessionData[fragIndex].FragGroupData.FragSize ) - FragSessionData[fragIndex].FragGroupData.Padding ); + } + FragSessionData[fragIndex].FragDecoderProcessStatus = FRAG_SESSION_NOT_STARTED; + } + } + cmdIndex += FragSessionData[fragIndex].FragGroupData.FragSize; + break; + } + default: + { + break; + } } - uint8_t status = 0x00; - uint8_t id = mcpsIndication->Buffer[cmdIndex++] & 0x03; + } - status |= id; - if ((id >= FRAGMENTATION_MAX_SESSIONS) || (FragSessionData[id].FragGroupData.IsActive == false)) - { - status |= 0x04; /* Session does not exist */ - } - else - { - /* Delete session */ - FragSessionData[id].FragGroupData.IsActive = false; - } - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = FRAGMENTATION_FRAG_SESSION_DELETE_ANS; - LmhpFragmentationState.DataBuffer[dataBufferIndex++] = status; - isAnswerDelayed = false; - break; - } - case FRAGMENTATION_DATA_FRAGMENT: - { - uint8_t fragIndex = 0; - uint16_t fragCounter = 0; - - fragCounter = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x00FF; - fragCounter |= (mcpsIndication->Buffer[cmdIndex++] << 8) & 0xFF00; - - fragIndex = (fragCounter >> 14) & 0x03; - fragCounter &= 0x3FFF; - if (FragSessionData[fragIndex].FragGroupData.IsActive == false) - { - cmdIndex = mcpsIndication->BufferSize; - break; - } - if (mcpsIndication->Multicast == 1) - { - /* Message received on a multicast address */ - /* Check McGroupBitMask */ - uint8_t groupId = LoRaMacMcChannelGetGroupId(mcpsIndication->DevAddress); - if ((groupId == 0xFF) || - ((FragSessionData[fragIndex].FragGroupData.FragSession.Fields.McGroupBitMask & (1 << groupId)) == 0)) - { - /* Ignore message */ - cmdIndex = mcpsIndication->BufferSize; - break; - } - } + // After processing the commands, if the end-node has to reply back then a flag is checked if the + // reply is to be sent immediately or with a delay. + // In some scenarios it is not desired that multiple end-notes send uplinks at the same time to + // the same server. (Example: Fragment status during a multicast FUOTA) + if( dataBufferIndex != 0 ) + { + // Prepare Answer that is to be transmitted + cmdReplyAppData.Buffer = LmhpFragmentationState.DataBuffer; + cmdReplyAppData.BufferSize = dataBufferIndex; + cmdReplyAppData.Port = FRAGMENTATION_PORT; - if (FragSessionData[fragIndex].FragDecoderProcessStatus == FRAG_SESSION_ONGOING) + if( isAnswerDelayed == true ) { - FragSessionData[fragIndex].FragDecoderProcessStatus = FragDecoderProcess(fragCounter, &mcpsIndication->Buffer[cmdIndex]); - FragSessionData[fragIndex].FragDecoderStatus = FragDecoderGetStatus(); - if (LmhpFragmentationParams->OnProgress != NULL) - { - LmhpFragmentationParams->OnProgress(FragSessionData[fragIndex].FragDecoderStatus.FragNbRx, - FragSessionData[fragIndex].FragGroupData.FragNb, - FragSessionData[fragIndex].FragGroupData.FragSize, - FragSessionData[fragIndex].FragDecoderStatus.FragNbLost); - } + // Delay value is calculated using BlockAckDelay which is communicated by server during the FragSessionSetupReq + // Pseudo Random Delay = rand(0:1) * 2^(blockAckDelay + 4) Seconds. + // Delay = Pseudo Random Delay * 1000 milli seconds. + // Eg: blockAckDelay = 7 + // Pseudo Random Delay = rand(0:1) * 2^11 + // rand(0:1) seconds = rand(0:1000) milliseconds + // Delay = rand(0:1000) * 2048 => 2048000ms = 34 minutes + TxDelayTime = randr( 0, 1000 ) * ( 1 << ( blockAckDelay + 4 ) ); + DelayedReplyAppData = cmdReplyAppData; + LmhpFragmentationState.TxDelayState = FRAGMENTATION_TX_DELAY_STATE_START; + LmhpFragmentationPackage.OnPackageProcessEvent(); } else { - if (FragSessionData[fragIndex].FragDecoderProcessStatus >= 0) - { - /* Fragmentation successfully done */ - if (LmhpFragmentationParams->OnDone != NULL) - { - LmhpFragmentationParams->OnDone(FragSessionData[fragIndex].FragDecoderProcessStatus, - (FragSessionData[fragIndex].FragGroupData.FragNb * FragSessionData[fragIndex].FragGroupData.FragSize) - - FragSessionData[fragIndex].FragGroupData.Padding); - } - FragSessionData[fragIndex].FragDecoderProcessStatus = FRAG_SESSION_NOT_STARTED; - } - } - cmdIndex += FragSessionData[fragIndex].FragGroupData.FragSize; - break; - } - default: - { - break; - } - } - } - - /* After processing the commands, if the end-node has to reply back then a flag is checked if the */ - /* reply is to be sent immediately or with a delay. */ - /* In some scenarios it is not desired that multiple end-notes send uplinks at the same time to */ - /* the same server. (Example: Fragment status during a multicast FUOTA) */ - if (dataBufferIndex != 0) - { - /* Answer commands */ - LmHandlerAppData_t appData = - { - .Buffer = LmhpFragmentationState.DataBuffer, - .BufferSize = dataBufferIndex, - .Port = FRAGMENTATION_PORT - }; - - if (isAnswerDelayed == true) - { - /* Delay value is calculated using BlockAckDelay which is communicated by server during the FragSessionSetupReq */ - /* Pseudo Random Delay = rand(0:1) * 2^(blockAckDelay + 4) Seconds. */ - /* Delay = Pseudo Random Delay * 1000 milli seconds. */ - /* Eg: blockAckDelay = 7 */ - /* Pseudo Random Delay = rand(0:1) * 2^11 */ - /* rand(0:1) seconds = rand(0:1000) milliseconds */ - /* Delay = rand(0:1000) * 2048 => 2048000ms = 34 minutes */ - TxDelayTime = randr(0, 1000) * (1 << (blockAckDelay + 4)); - DelayedReplyAppData = appData; - LmhpFragmentationState.TxDelayState = FRAGMENTATION_TX_DELAY_STATE_START; - } - else - { - /* Send the prepared answer */ - bool current_dutycycle; - LmHandlerGetDutyCycleEnable(¤t_dutycycle); + // Send the prepared answer + bool current_dutycycle; + LmHandlerGetDutyCycleEnable( ¤t_dutycycle ); - /* force Duty Cycle OFF to this Send */ - LmHandlerSetDutyCycleEnable(false); - LmhpFragmentationPackage.OnSendRequest(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); + /* force Duty Cycle OFF to this Send */ + LmHandlerSetDutyCycleEnable( false ); + LmhpFragmentationPackage.OnSendRequest( &cmdReplyAppData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true ); - /* restore initial Duty Cycle */ - LmHandlerSetDutyCycleEnable(current_dutycycle); + /* restore initial Duty Cycle */ + LmHandlerSetDutyCycleEnable( current_dutycycle ); + } } - } } diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.h index d8d0fdc6..794d3dd0 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpFragmentation.h @@ -1,46 +1,32 @@ /*! - * \file LmhpFragmentation.h - * - * \brief Implements the LoRa-Alliance fragmented data block transport package - * Specification: https://lora-alliance.org/sites/default/files/2018-09/fragmented_data_block_transport_v1.0.0.pdf - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2013-2018 Semtech - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - */ -/** - ****************************************************************************** - * - * Portions COPYRIGHT 2020 STMicroelectronics - * - * @file LmhpFragmentation.h - * @author MCD Application Team - * @brief Header for Fragmentation Data Block Transport Package module - ****************************************************************************** - */ + * \file LmhpFragmentation.h + * + * \brief Implements the LoRa-Alliance fragmented data block transport package + * Specification: https://lora-alliance.org/sites/default/files/2018-09/fragmented_data_block_transport_v1.0.0.pdf + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2018 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + */ #ifndef __LMHP_FRAGMENTATION_H__ #define __LMHP_FRAGMENTATION_H__ -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ +#include "LoRaMac.h" +#include "LmHandlerTypes.h" #include "LmhPackage.h" #include "FragDecoder.h" -/* Exported defines ----------------------------------------------------------*/ /*! * Fragmentation data block transport package identifier. * @@ -48,44 +34,37 @@ extern "C" { */ #define PACKAGE_ID_FRAGMENTATION 3 -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ /*! * Fragmentation package parameters */ typedef struct LmhpFragmentationParams_s { - /*! - * FragDecoder Write/Read function callbacks - */ - FragDecoderCallbacks_t DecoderCallbacks; - /*! - * Notifies the progress of the current fragmentation session - * - * \param [in] fragCounter Fragment counter - * \param [in] fragNb Number of fragments - * \param [in] fragSize Size of fragments - * \param [in] fragNbLost Number of lost fragments - */ - void (*OnProgress)(uint16_t fragCounter, uint16_t fragNb, uint8_t fragSize, uint16_t fragNbLost); - /*! - * Notifies that the fragmentation session is finished - * - * \param [in] status Fragmentation session status [FRAG_SESSION_ONGOING, - * FRAG_SESSION_FINISHED or - * FragDecoder.Status.FragNbLost] - * \param [in] size Received file size - */ - void (*OnDone)(int32_t status, uint32_t size); -} LmhpFragmentationParams_t; + /*! + * FragDecoder Write/Read function callbacks + */ + FragDecoderCallbacks_t DecoderCallbacks; + /*! + * Notifies the progress of the current fragmentation session + * + * \param [IN] fragCounter Fragment counter + * \param [IN] fragNb Number of fragments + * \param [IN] fragSize Size of fragments + * \param [IN] fragNbLost Number of lost fragments + */ + void ( *OnProgress )( uint16_t fragCounter, uint16_t fragNb, uint8_t fragSize, uint16_t fragNbLost ); + /*! + * Notifies that the fragmentation session is finished + * + * \param [IN] status Fragmentation session status [FRAG_SESSION_ONGOING, + * FRAG_SESSION_FINISHED or + * FragDecoder.Status.FragNbLost] + * \param [IN] size Received file size + */ + void ( *OnDone )( int32_t status, uint32_t size ); +}LmhpFragmentationParams_t; -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -LmhPackage_t *LmhpFragmentationPackageFactory(void); +LmhPackage_t *LmhpFragmentationPackageFactory( void ); -#ifdef __cplusplus -} -#endif +uint8_t LmhpFragmentationGetPackageVersion(void); -#endif /* __LMHP_FRAGMENTATION_H__ */ +#endif // __LMHP_FRAGMENTATION_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpPackagesRegistration.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpPackagesRegistration.c new file mode 100644 index 00000000..e90d5bce --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpPackagesRegistration.c @@ -0,0 +1,94 @@ +/** + ****************************************************************************** + * @file LmhpPackagesRegistration.c + * @author MCD Application Team + * @brief Implements the Packages Registration Agent + ****************************************************************************** + * @attention + * + *

    © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

    + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "platform.h" +#include "LmhpPackagesRegistration.h" +#include "LmhpClockSync.h" +#include "LmhpRemoteMcastSetup.h" +#include "LmhpFragmentation.h" +#include "LmhpFirmwareManagement.h" +#include "LmHandler.h" +#include "frag_decoder_if.h" + +/* Private typedef -----------------------------------------------------------*/ + +/* Private define ------------------------------------------------------------*/ + +/* Private macro -------------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ + +/* Exported functions ---------------------------------------------------------*/ +LmHandlerErrorStatus_t LmhpPackagesRegistrationInit(void) +{ + if (LmHandlerPackageRegister(PACKAGE_ID_CLOCK_SYNC, NULL) != LORAMAC_HANDLER_SUCCESS) + { + return LORAMAC_HANDLER_ERROR; + } + else if (LmHandlerPackageRegister(PACKAGE_ID_REMOTE_MCAST_SETUP, NULL) != LORAMAC_HANDLER_SUCCESS) + { + return LORAMAC_HANDLER_ERROR; + } + else if (LmHandlerPackageRegister(PACKAGE_ID_FRAGMENTATION, (LmhpFragmentationParams_t *)&FRAG_DECODER_IF_FragmentationParams) != LORAMAC_HANDLER_SUCCESS) + { + return LORAMAC_HANDLER_ERROR; + } + else if (LmHandlerPackageRegister(PACKAGE_ID_FIRMWARE_MANAGEMENT, NULL) != LORAMAC_HANDLER_SUCCESS) + { + return LORAMAC_HANDLER_ERROR; + } + + return LORAMAC_HANDLER_SUCCESS; +} + +LmHandlerErrorStatus_t LmhpPackagesRegister(uint8_t id, LmhPackage_t **package) +{ + if (package == NULL) + { + return LORAMAC_HANDLER_ERROR; + } + switch (id) + { + case PACKAGE_ID_CLOCK_SYNC: + { + *package = LmhpClockSyncPackageFactory(); + break; + } + case PACKAGE_ID_REMOTE_MCAST_SETUP: + { + *package = LmhpRemoteMcastSetupPackageFactory(); + break; + } + case PACKAGE_ID_FRAGMENTATION: + { + *package = LmhpFragmentationPackageFactory(); + break; + } + case PACKAGE_ID_FIRMWARE_MANAGEMENT: + { + *package = LmhpFirmwareManagementPackageFactory(); + break; + } + } + + return LORAMAC_HANDLER_SUCCESS; +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpPackagesRegistration.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpPackagesRegistration.h new file mode 100644 index 00000000..8ac70364 --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpPackagesRegistration.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * @file LmhpPackagesRegistration.h + * @author MCD Application Team + * @brief Function prototypes for LoRaMac Packages Registration agent + ****************************************************************************** + * @attention + * + *

    © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

    + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +#ifndef __LMHP_PACKAGES_REGISTRATION_H__ +#define __LMHP_PACKAGES_REGISTRATION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "LmhPackage.h" + +/* Exported defines ----------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* External variables --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +LmHandlerErrorStatus_t LmhpPackagesRegistrationInit(void); + +LmHandlerErrorStatus_t LmhpPackagesRegister(uint8_t id, LmhPackage_t **package); + +#ifdef __cplusplus +} +#endif + +#endif /* __LMHP_PACKAGES_REGISTRATION_H__ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.c b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.c index 8c64161e..e56539ea 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.c +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.c @@ -34,97 +34,61 @@ #include "LmhpRemoteMcastSetup.h" #include "mw_log_conf.h" /* needed for MW_LOG */ -/* Private typedef -----------------------------------------------------------*/ +/*! + * LoRaWAN Application Layer Remote multicast setup Specification + */ +#define REMOTE_MCAST_SETUP_PORT 200 + +#define REMOTE_MCAST_SETUP_ID 2 +#define REMOTE_MCAST_SETUP_VERSION 1 + typedef enum LmhpRemoteMcastSetupSessionStates_e { - REMOTE_MCAST_SETUP_SESSION_STATE_IDLE, - REMOTE_MCAST_SETUP_SESSION_STATE_START, - REMOTE_MCAST_SETUP_SESSION_STATE_STOP, -} LmhpRemoteMcastSetupSessionStates_t; + REMOTE_MCAST_SETUP_SESSION_STATE_IDLE, + REMOTE_MCAST_SETUP_SESSION_STATE_START, + REMOTE_MCAST_SETUP_SESSION_STATE_STOP, +}LmhpRemoteMcastSetupSessionStates_t; /*! * Package current context */ typedef struct LmhpRemoteMcastSetupState_s { - bool Initialized; - bool IsRunning; - LmhpRemoteMcastSetupSessionStates_t SessionState; - uint8_t DataBufferMaxSize; - uint8_t *DataBuffer; -} LmhpRemoteMcastSetupState_t; + bool Initialized; + bool IsRunning; + LmhpRemoteMcastSetupSessionStates_t SessionState; + uint8_t DataBufferMaxSize; + uint8_t *DataBuffer; +}LmhpRemoteMcastSetupState_t; typedef enum LmhpRemoteMcastSetupMoteCmd_e { - REMOTE_MCAST_SETUP_PKG_VERSION_ANS = 0x00, - REMOTE_MCAST_SETUP_MC_GROUP_STATUS_ANS = 0x01, - REMOTE_MCAST_SETUP_MC_GROUP_SETUP_ANS = 0x02, - REMOTE_MCAST_SETUP_MC_GROUP_DELETE_ANS = 0x03, - REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_ANS = 0x04, - REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_ANS = 0x05, -} LmhpRemoteMcastSetupMoteCmd_t; + REMOTE_MCAST_SETUP_PKG_VERSION_ANS = 0x00, + REMOTE_MCAST_SETUP_MC_GROUP_STATUS_ANS = 0x01, + REMOTE_MCAST_SETUP_MC_GROUP_SETUP_ANS = 0x02, + REMOTE_MCAST_SETUP_MC_GROUP_DELETE_ANS = 0x03, + REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_ANS = 0x04, + REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_ANS = 0x05, +}LmhpRemoteMcastSetupMoteCmd_t; typedef enum LmhpRemoteMcastSetupSrvCmd_e { - REMOTE_MCAST_SETUP_PKG_VERSION_REQ = 0x00, - REMOTE_MCAST_SETUP_MC_GROUP_STATUS_REQ = 0x01, - REMOTE_MCAST_SETUP_MC_GROUP_SETUP_REQ = 0x02, - REMOTE_MCAST_SETUP_MC_GROUP_DELETE_REQ = 0x03, - REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ = 0x04, - REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ = 0x05, -} LmhpRemoteMcastSetupSrvCmd_t; - -typedef struct McGroupData_s -{ - uint8_t McGroupEnabled; - union - { - uint8_t Value; - struct - { - uint8_t McGroupId: 2; - uint8_t RFU: 6; - } Fields; - } IdHeader; - uint32_t McAddr; - uint8_t McKeyEncrypted[16]; - uint32_t McFCountMin; /*! */ - uint32_t McFCountMax; -} McGroupData_t; + REMOTE_MCAST_SETUP_PKG_VERSION_REQ = 0x00, + REMOTE_MCAST_SETUP_MC_GROUP_STATUS_REQ = 0x01, + REMOTE_MCAST_SETUP_MC_GROUP_SETUP_REQ = 0x02, + REMOTE_MCAST_SETUP_MC_GROUP_DELETE_REQ = 0x03, + REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ = 0x04, + REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ = 0x05, +}LmhpRemoteMcastSetupSrvCmd_t; -typedef enum eSessionState -{ - SESSION_STOPPED, - SESSION_STARTED -} SessionState_t; - -typedef struct McSessionData_s -{ - McGroupData_t McGroupData; - SessionState_t SessionState; - uint32_t SessionTime; - uint8_t SessionTimeout; - McRxParams_t RxParams; -} McSessionData_t; - -/* Private define ------------------------------------------------------------*/ -/*! - * LoRaWAN Application Layer Remote multicast setup Specification - */ -#define REMOTE_MCAST_SETUP_PORT 200 -#define REMOTE_MCAST_SETUP_ID 2 -#define REMOTE_MCAST_SETUP_VERSION 1 - -/* Private macro -------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ /*! * Initializes the package with provided parameters * - * \param [in] params Pointer to the package parameters - * \param [in] dataBuffer Pointer to main application buffer - * \param [in] dataBufferMaxSize Main application buffer maximum size + * \param [IN] params Pointer to the package parameters + * \param [IN] dataBuffer Pointer to main application buffer + * \param [IN] dataBufferMaxSize Main application buffer maximum size */ -static void LmhpRemoteMcastSetupInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize); +static void LmhpRemoteMcastSetupInit( void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ); /*! * Returns the current package initialization status. @@ -132,7 +96,7 @@ static void LmhpRemoteMcastSetupInit(void *params, uint8_t *dataBuffer, uint8_t * \retval status Package initialization status * [true: Initialized, false: Not initialized] */ -static bool LmhpRemoteMcastSetupIsInitialized(void); +static bool LmhpRemoteMcastSetupIsInitialized( void ); /*! * Returns the package operation status. @@ -140,32 +104,64 @@ static bool LmhpRemoteMcastSetupIsInitialized(void); * \retval status Package operation status * [true: Running, false: Not running] */ -static bool LmhpRemoteMcastSetupIsRunning(void); +static bool LmhpRemoteMcastSetupIsRunning( void ); /*! * Processes the internal package events. */ -static void LmhpRemoteMcastSetupProcess(void); +static void LmhpRemoteMcastSetupProcess( void ); /*! * Processes the MCPS Indication * - * \param [in] mcpsIndication MCPS indication primitive data + * \param [IN] mcpsIndication MCPS indication primitive data */ -static void LmhpRemoteMcastSetupOnMcpsIndication(McpsIndication_t *mcpsIndication); +static void LmhpRemoteMcastSetupOnMcpsIndication( McpsIndication_t *mcpsIndication ); -static void OnSessionStartTimer(void *context); +static void OnSessionStartTimer( void *context ); -static void OnSessionStopTimer(void *context); +static void OnSessionStopTimer( void *context ); -/* Private variables ---------------------------------------------------------*/ static LmhpRemoteMcastSetupState_t LmhpRemoteMcastSetupState = { - .Initialized = false, - .IsRunning = false, - .SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE, + .Initialized = false, + .IsRunning = false, + .SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE, }; +typedef struct McGroupData_s +{ + uint8_t McGroupEnabled; + union + { + uint8_t Value; + struct + { + uint8_t McGroupId: 2; + uint8_t RFU: 6; + }Fields; + }IdHeader; + uint32_t McAddr; + uint8_t McKeyEncrypted[16]; + uint32_t McFCountMin; + uint32_t McFCountMax; +}McGroupData_t; + +typedef enum eSessionState +{ + SESSION_STOPPED, + SESSION_STARTED +}SessionState_t; + +typedef struct McSessionData_s +{ + McGroupData_t McGroupData; + SessionState_t SessionState; + uint32_t SessionTime; + uint8_t SessionTimeout; + McRxParams_t RxParams; +}McSessionData_t; + static McSessionData_t McSessionData[LORAMAC_MAX_MC_CTX]; /*! @@ -180,340 +176,355 @@ static TimerEvent_t SessionStopTimer; static LmhPackage_t LmhpRemoteMcastSetupPackage = { - .Port = REMOTE_MCAST_SETUP_PORT, - .Init = LmhpRemoteMcastSetupInit, - .IsInitialized = LmhpRemoteMcastSetupIsInitialized, - .IsRunning = LmhpRemoteMcastSetupIsRunning, - .Process = LmhpRemoteMcastSetupProcess, - .OnMcpsConfirmProcess = NULL, /* Not used in this package */ - .OnMcpsIndicationProcess = LmhpRemoteMcastSetupOnMcpsIndication, - .OnMlmeConfirmProcess = NULL, /* Not used in this package */ - .OnJoinRequest = NULL, /* To be initialized by LmHandler */ - .OnSendRequest = NULL, /* To be initialized by LmHandler */ - .OnDeviceTimeRequest = NULL, /* To be initialized by LmHandler */ + .Port = REMOTE_MCAST_SETUP_PORT, + .Init = LmhpRemoteMcastSetupInit, + .IsInitialized = LmhpRemoteMcastSetupIsInitialized, + .IsRunning = LmhpRemoteMcastSetupIsRunning, + .Process = LmhpRemoteMcastSetupProcess, + .OnMcpsConfirmProcess = NULL, // Not used in this package + .OnMcpsIndicationProcess = LmhpRemoteMcastSetupOnMcpsIndication, + .OnMlmeConfirmProcess = NULL, // Not used in this package + .OnJoinRequest = NULL, // To be initialized by LmHandler + .OnSendRequest = NULL, // To be initialized by LmHandler + .OnDeviceTimeRequest = NULL, // To be initialized by LmHandler + .OnSysTimeUpdate = NULL, // To be initialized by LmHandler + .OnPackageProcessEvent = NULL, // To be initialized by LmHandler }; -/* Exported functions ---------------------------------------------------------*/ -LmhPackage_t *LmhpRemoteMcastSetupPackageFactory(void) +LmhPackage_t *LmhpRemoteMcastSetupPackageFactory( void ) { - return &LmhpRemoteMcastSetupPackage; + return &LmhpRemoteMcastSetupPackage; } -/* Private functions ---------------------------------------------------------*/ -static void LmhpRemoteMcastSetupInit(void *params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize) +static void LmhpRemoteMcastSetupInit( void * params, uint8_t *dataBuffer, uint8_t dataBufferMaxSize ) { - if (dataBuffer != NULL) - { - LmhpRemoteMcastSetupState.DataBuffer = dataBuffer; - LmhpRemoteMcastSetupState.DataBufferMaxSize = dataBufferMaxSize; - LmhpRemoteMcastSetupState.Initialized = true; - LmhpRemoteMcastSetupState.IsRunning = true; - TimerInit(&SessionStartTimer, OnSessionStartTimer); - TimerInit(&SessionStopTimer, OnSessionStopTimer); - } - else - { - LmhpRemoteMcastSetupState.IsRunning = false; - LmhpRemoteMcastSetupState.Initialized = false; - } - - for (uint8_t id = 0; id < LORAMAC_MAX_MC_CTX; id++) - { - McSessionData[id].McGroupData.McGroupEnabled = false; - } + if( dataBuffer != NULL ) + { + LmhpRemoteMcastSetupState.DataBuffer = dataBuffer; + LmhpRemoteMcastSetupState.DataBufferMaxSize = dataBufferMaxSize; + LmhpRemoteMcastSetupState.Initialized = true; + LmhpRemoteMcastSetupState.IsRunning = true; + TimerInit( &SessionStartTimer, OnSessionStartTimer ); + TimerInit( &SessionStopTimer, OnSessionStopTimer ); + } + else + { + LmhpRemoteMcastSetupState.IsRunning = false; + LmhpRemoteMcastSetupState.Initialized = false; + } + + for (uint8_t id = 0; id < LORAMAC_MAX_MC_CTX; id++) + { + McSessionData[id].McGroupData.McGroupEnabled = false; + } } -static bool LmhpRemoteMcastSetupIsInitialized(void) +static bool LmhpRemoteMcastSetupIsInitialized( void ) { - return LmhpRemoteMcastSetupState.Initialized; + return LmhpRemoteMcastSetupState.Initialized; } -static bool LmhpRemoteMcastSetupIsRunning(void) +static bool LmhpRemoteMcastSetupIsRunning( void ) { - if (LmhpRemoteMcastSetupState.Initialized == false) - { - return false; - } + if( LmhpRemoteMcastSetupState.Initialized == false ) + { + return false; + } - return LmhpRemoteMcastSetupState.IsRunning; + return LmhpRemoteMcastSetupState.IsRunning; } -static void LmhpRemoteMcastSetupProcess(void) +static void LmhpRemoteMcastSetupProcess( void ) { - LmhpRemoteMcastSetupSessionStates_t state; - - CRITICAL_SECTION_BEGIN(); - state = LmhpRemoteMcastSetupState.SessionState; - CRITICAL_SECTION_END(); - - switch (state) - { - case REMOTE_MCAST_SETUP_SESSION_STATE_START: - /* Switch to Class C */ - - if (LmHandlerRequestClass(CLASS_C) == LORAMAC_HANDLER_SUCCESS) - { - LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE; - - TimerSetValue(&SessionStopTimer, (1 << McSessionData[0].SessionTimeout) * 1000); - TimerStart(&SessionStopTimer); - } - break; - case REMOTE_MCAST_SETUP_SESSION_STATE_STOP: - /* Switch back to Class A */ - if (LmHandlerRequestClass(CLASS_A) == LORAMAC_HANDLER_SUCCESS) - { - LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE; - } - break; - case REMOTE_MCAST_SETUP_SESSION_STATE_IDLE: - /* Intentional fall through */ - default: - /* Nothing to do. */ - break; - } -} + LmhpRemoteMcastSetupSessionStates_t state; -static void LmhpRemoteMcastSetupOnMcpsIndication(McpsIndication_t *mcpsIndication) -{ - uint8_t cmdIndex = 0; - uint8_t dataBufferIndex = 0; - uint8_t id = 0xFF; + CRITICAL_SECTION_BEGIN( ); + state = LmhpRemoteMcastSetupState.SessionState; + CRITICAL_SECTION_END( ); - while (cmdIndex < mcpsIndication->BufferSize) - { - switch (mcpsIndication->Buffer[cmdIndex++]) + switch( state ) { - case REMOTE_MCAST_SETUP_PKG_VERSION_REQ: - { - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_PKG_VERSION_ANS; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_ID; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_VERSION; - break; - } - case REMOTE_MCAST_SETUP_MC_GROUP_STATUS_REQ: - { - uint8_t nbAvailableGroups = 0; - uint8_t reqGroupMask = mcpsIndication->Buffer[cmdIndex++] & 0x0F; - uint8_t AnsGroupMask = 0x00; - - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_STATUS_ANS; - - /* move index to the next first optional list */ - dataBufferIndex++; - for (id = 0; id < LORAMAC_MAX_MC_CTX; id++) - { - if (McSessionData[id].McGroupData.McGroupEnabled) - { - nbAvailableGroups++; + case REMOTE_MCAST_SETUP_SESSION_STATE_START: + // Switch to Class C - /* If multicast group defined in the input bit mask */ - if ((reqGroupMask & (1 << id)) != 0) + if ( LmHandlerRequestClass( CLASS_C ) == LORAMAC_HANDLER_SUCCESS ) { - AnsGroupMask |= (1 << id); - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = id; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 0) & 0xFF; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 8) & 0xFF; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 16) & 0xFF; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 24) & 0xFF; - } - } - } - /* set the status bit */ - LmhpRemoteMcastSetupState.DataBuffer[1] = (nbAvailableGroups & 0x07) << 4 | (AnsGroupMask & 0x0F); + LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE; - break; - } - case REMOTE_MCAST_SETUP_MC_GROUP_SETUP_REQ: - { - uint8_t status = id = mcpsIndication->Buffer[cmdIndex++] & 0x03; - McSessionData[id].McGroupData.IdHeader.Value = id; + TimerSetValue( &SessionStopTimer, ( 1 << McSessionData[0].SessionTimeout ) * 1000 ); + TimerStart(&SessionStopTimer); + } + else + { + TimerSetValue( &SessionStartTimer, 1000 ); + TimerStart(&SessionStartTimer); + } + break; + case REMOTE_MCAST_SETUP_SESSION_STATE_STOP: + // Switch back to Class A + if ( LmHandlerRequestClass( CLASS_A ) == LORAMAC_HANDLER_SUCCESS ) + { + LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_IDLE; + } + else + { + TimerSetValue( &SessionStopTimer, 1000 ); + TimerStart(&SessionStopTimer); + } + break; + case REMOTE_MCAST_SETUP_SESSION_STATE_IDLE: + break; + default: + break; + } +} +static void LmhpRemoteMcastSetupOnMcpsIndication( McpsIndication_t *mcpsIndication ) +{ + uint8_t cmdIndex = 0; + uint8_t dataBufferIndex = 0; + uint8_t id = 0xFF; - McSessionData[id].McGroupData.McAddr = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x000000FF; - McSessionData[id].McGroupData.McAddr += (mcpsIndication->Buffer[cmdIndex++] << 8) & 0x0000FF00; - McSessionData[id].McGroupData.McAddr += (mcpsIndication->Buffer[cmdIndex++] << 16) & 0x00FF0000; - McSessionData[id].McGroupData.McAddr += (mcpsIndication->Buffer[cmdIndex++] << 24) & 0xFF000000; + if( mcpsIndication->Port != REMOTE_MCAST_SETUP_PORT ) + { + return; + } - for (int8_t i = 0; i < 16; i++) + while( cmdIndex < mcpsIndication->BufferSize ) + { + switch( mcpsIndication->Buffer[cmdIndex++] ) { - McSessionData[id].McGroupData.McKeyEncrypted[i] = mcpsIndication->Buffer[cmdIndex++]; + case REMOTE_MCAST_SETUP_PKG_VERSION_REQ: + { + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_PKG_VERSION_ANS; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_ID; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_VERSION; + break; + } + case REMOTE_MCAST_SETUP_MC_GROUP_STATUS_REQ: + { + uint8_t nbAvailableGroups = 0; + uint8_t reqGroupMask = mcpsIndication->Buffer[cmdIndex++] & 0x0F; + uint8_t AnsGroupMask = 0x00; + + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_STATUS_ANS; + + /* move index to the next first optional list */ + dataBufferIndex++; + for (id = 0; id < LORAMAC_MAX_MC_CTX; id++) + { + if( McSessionData[id].McGroupData.McGroupEnabled ) + { + nbAvailableGroups++; + + /* If multicast group defined in the input bit mask */ + if( ( reqGroupMask & ( 1 << id ) ) != 0 ) + { + AnsGroupMask |= (1 << id); + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = id; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 0) & 0xFF; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 8) & 0xFF; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 16) & 0xFF; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (McSessionData[id].McGroupData.McAddr >> 24) & 0xFF; + } + } + } + /* set the status bit */ + LmhpRemoteMcastSetupState.DataBuffer[1] = (nbAvailableGroups & 0x07) << 4 | (AnsGroupMask & 0x0F); + + break; + } + case REMOTE_MCAST_SETUP_MC_GROUP_SETUP_REQ: + { + id = mcpsIndication->Buffer[cmdIndex++] & 0x03; + McSessionData[id].McGroupData.IdHeader.Value = id; + + McSessionData[id].McGroupData.McAddr = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF; + McSessionData[id].McGroupData.McAddr += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00; + McSessionData[id].McGroupData.McAddr += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000; + McSessionData[id].McGroupData.McAddr += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000; + + for( int8_t i = 0; i < 16; i++ ) + { + McSessionData[id].McGroupData.McKeyEncrypted[i] = mcpsIndication->Buffer[cmdIndex++]; + } + + McSessionData[id].McGroupData.McFCountMin = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF; + McSessionData[id].McGroupData.McFCountMin += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00; + McSessionData[id].McGroupData.McFCountMin += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000; + McSessionData[id].McGroupData.McFCountMin += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000; + + McSessionData[id].McGroupData.McFCountMax = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF; + McSessionData[id].McGroupData.McFCountMax += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00; + McSessionData[id].McGroupData.McFCountMax += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000; + McSessionData[id].McGroupData.McFCountMax += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000; + + McChannelParams_t channel = + { + .IsRemotelySetup = true, + .Class = CLASS_C, // Field not used for multicast channel setup. Must be initialized to something + .IsEnabled = true, + .GroupID = ( AddressIdentifier_t )McSessionData[id].McGroupData.IdHeader.Fields.McGroupId, + .Address = McSessionData[id].McGroupData.McAddr, + .McKeys.McKeyE = McSessionData[id].McGroupData.McKeyEncrypted, + .FCountMin = McSessionData[id].McGroupData.McFCountMin, + .FCountMax = McSessionData[id].McGroupData.McFCountMax, + .RxParams.ClassC = // Field not used for multicast channel setup. Must be initialized to something + { + .Frequency = 0, + .Datarate = 0 + } + }; + uint8_t idError = 0x01; // One bit value + if( LoRaMacMcChannelSetup( &channel ) == LORAMAC_STATUS_OK ) + { + idError = 0x00; + McSessionData[id].McGroupData.McGroupEnabled = true; + } + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_SETUP_ANS; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = ( idError << 2 ) | McSessionData[id].McGroupData.IdHeader.Fields.McGroupId; + break; + } + case REMOTE_MCAST_SETUP_MC_GROUP_DELETE_REQ: + { + uint8_t status = 0x00; + id = mcpsIndication->Buffer[cmdIndex++] & 0x03; + + status = id; + McSessionData[id].McGroupData.IdHeader.Value = 0; + McSessionData[id].McGroupData.McAddr = 0; + UTIL_MEM_set_8( McSessionData[id].McGroupData.McKeyEncrypted, 0x00, 16 ); + McSessionData[id].McGroupData.McFCountMin = 0; + McSessionData[id].McGroupData.McFCountMax = 0; + + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_DELETE_ANS; + + if( LoRaMacMcChannelDelete( ( AddressIdentifier_t )id ) != LORAMAC_STATUS_OK ) + { + status |= 0x04; // McGroupUndefined bit set + } + else + { + McSessionData[id].McGroupData.McGroupEnabled = false; + } + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status; + break; + } + case REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ: + { + uint8_t status = 0x00; + int32_t timeToSessionStart = 0; + id = mcpsIndication->Buffer[cmdIndex++] & 0x03; + + McSessionData[id].SessionTime = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF; + McSessionData[id].SessionTime += ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00; + McSessionData[id].SessionTime += ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000; + McSessionData[id].SessionTime += ( mcpsIndication->Buffer[cmdIndex++] << 24 ) & 0xFF000000; + + // Add Unix to Gps epoch offset. The system time is based on Unix time. + McSessionData[id].SessionTime += UNIX_GPS_EPOCH_OFFSET; + + McSessionData[id].SessionTimeout = mcpsIndication->Buffer[cmdIndex++] & 0x0F; + + McSessionData[id].RxParams.ClassC.Frequency = ( mcpsIndication->Buffer[cmdIndex++] << 0 ) & 0x000000FF; + McSessionData[id].RxParams.ClassC.Frequency |= ( mcpsIndication->Buffer[cmdIndex++] << 8 ) & 0x0000FF00; + McSessionData[id].RxParams.ClassC.Frequency |= ( mcpsIndication->Buffer[cmdIndex++] << 16 ) & 0x00FF0000; + McSessionData[id].RxParams.ClassC.Frequency *= 100; + + McSessionData[id].RxParams.ClassC.Datarate = mcpsIndication->Buffer[cmdIndex++]; + + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_ANS; + if( LoRaMacMcChannelSetupRxParams( ( AddressIdentifier_t )id, &McSessionData[id].RxParams, &status ) == LORAMAC_STATUS_OK ) + { + SysTime_t curTime = { .Seconds = 0, .SubSeconds = 0 }; + curTime = SysTimeGet( ); + + timeToSessionStart = McSessionData[id].SessionTime - curTime.Seconds; + if( timeToSessionStart > 0 ) + { + // Start session start timer + TimerSetValue( &SessionStartTimer, timeToSessionStart * 1000 ); + TimerStart( &SessionStartTimer ); + + MW_LOG(TS_OFF, VLEVEL_M, "Time2SessionStart: %d ms\r\n", timeToSessionStart * 1000); + } + else + { + // Session start time before current device time + status |= 0x10; + } + } + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status; + if( status == 0x00 ) + { + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 0) & 0xFF; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 8) & 0xFF; + LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 16) & 0xFF; + } + break; + } + case REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ: + { + // implement command prosessing and handling + break; + } + default: + { + break; + } } + } - McSessionData[id].McGroupData.McFCountMin = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x000000FF; - McSessionData[id].McGroupData.McFCountMin += (mcpsIndication->Buffer[cmdIndex++] << 8) & 0x0000FF00; - McSessionData[id].McGroupData.McFCountMin += (mcpsIndication->Buffer[cmdIndex++] << 16) & 0x00FF0000; - McSessionData[id].McGroupData.McFCountMin += (mcpsIndication->Buffer[cmdIndex++] << 24) & 0xFF000000; - - McSessionData[id].McGroupData.McFCountMax = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x000000FF; - McSessionData[id].McGroupData.McFCountMax += (mcpsIndication->Buffer[cmdIndex++] << 8) & 0x0000FF00; - McSessionData[id].McGroupData.McFCountMax += (mcpsIndication->Buffer[cmdIndex++] << 16) & 0x00FF0000; - McSessionData[id].McGroupData.McFCountMax += (mcpsIndication->Buffer[cmdIndex++] << 24) & 0xFF000000; - - McChannelParams_t channel = + if( dataBufferIndex != 0 ) + { + // Answer commands + LmHandlerAppData_t appData = { - .IsRemotelySetup = true, - .Class = CLASS_C, /* Field not used for multicast channel setup. Must be initialized to something */ - .IsEnabled = true, - .GroupID = (AddressIdentifier_t)McSessionData[id].McGroupData.IdHeader.Fields.McGroupId, - .Address = McSessionData[id].McGroupData.McAddr, - .McKeys.McKeyE = McSessionData[id].McGroupData.McKeyEncrypted, - .FCountMin = McSessionData[id].McGroupData.McFCountMin, - .FCountMax = McSessionData[id].McGroupData.McFCountMax, - .RxParams.ClassC = /* Field not used for multicast channel setup. Must be initialized to something */ - { - .Frequency = 0, - .Datarate = 0 - } + .Buffer = LmhpRemoteMcastSetupState.DataBuffer, + .BufferSize = dataBufferIndex, + .Port = REMOTE_MCAST_SETUP_PORT }; - if (LoRaMacMcChannelSetup(&channel) != LORAMAC_STATUS_OK) - { - status |= 0x04; /* IDerror bit */ - } - else - { - McSessionData[id].McGroupData.McGroupEnabled = true; - } - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_SETUP_ANS; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status; + bool current_dutycycle; + LmHandlerGetDutyCycleEnable( ¤t_dutycycle ); - break; - } - case REMOTE_MCAST_SETUP_MC_GROUP_DELETE_REQ: - { - uint8_t status = id = mcpsIndication->Buffer[cmdIndex++] & 0x03; + /* force Duty Cycle OFF to this Send */ + LmHandlerSetDutyCycleEnable( false ); + LmhpRemoteMcastSetupPackage.OnSendRequest( &appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true ); - McSessionData[id].McGroupData.IdHeader.Value = 0; - McSessionData[id].McGroupData.McAddr = 0; - UTIL_MEM_set_8(McSessionData[id].McGroupData.McKeyEncrypted, 0x00, 16); - McSessionData[id].McGroupData.McFCountMin = 0; - McSessionData[id].McGroupData.McFCountMax = 0; + /* restore initial Duty Cycle */ + LmHandlerSetDutyCycleEnable( current_dutycycle ); - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_DELETE_ANS; - - if (LoRaMacMcChannelDelete((AddressIdentifier_t)id) != LORAMAC_STATUS_OK) - { - status |= 0x04; /* McGroupUndefined bit set */ - } - else + if (id != 0xFF && id < LORAMAC_MAX_MC_CTX) { - McSessionData[id].McGroupData.McGroupEnabled = false; - } - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status; - break; - } - case REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ: - { - uint8_t status = 0x00; - id = mcpsIndication->Buffer[cmdIndex++] & 0x03; - int32_t timeToSessionStart = 0; - - McSessionData[id].SessionTime = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x000000FF; - McSessionData[id].SessionTime += (mcpsIndication->Buffer[cmdIndex++] << 8) & 0x0000FF00; - McSessionData[id].SessionTime += (mcpsIndication->Buffer[cmdIndex++] << 16) & 0x00FF0000; - McSessionData[id].SessionTime += (mcpsIndication->Buffer[cmdIndex++] << 24) & 0xFF000000; - - /* Add Unix to Gps epcoh offset. The system time is based on Unix time. */ - McSessionData[id].SessionTime += UNIX_GPS_EPOCH_OFFSET; - - McSessionData[id].SessionTimeout = mcpsIndication->Buffer[cmdIndex++] & 0x0F; - - McSessionData[id].RxParams.ClassC.Frequency = (mcpsIndication->Buffer[cmdIndex++] << 0) & 0x000000FF; - McSessionData[id].RxParams.ClassC.Frequency |= (mcpsIndication->Buffer[cmdIndex++] << 8) & 0x0000FF00; - McSessionData[id].RxParams.ClassC.Frequency |= (mcpsIndication->Buffer[cmdIndex++] << 16) & 0x00FF0000; - McSessionData[id].RxParams.ClassC.Frequency *= 100; - - McSessionData[id].RxParams.ClassC.Datarate = mcpsIndication->Buffer[cmdIndex++]; - - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = REMOTE_MCAST_SETUP_MC_GROUP_CLASS_C_SESSION_ANS; - if (LoRaMacMcChannelSetupRxParams((AddressIdentifier_t)id, &McSessionData[id].RxParams, &status) == LORAMAC_STATUS_OK) - { - SysTime_t curTime = { .Seconds = 0, .SubSeconds = 0 }; - curTime = SysTimeGet(); - - if ((McSessionData[id].SessionTime - curTime.Seconds) > 0) - { - timeToSessionStart = McSessionData[id].SessionTime - curTime.Seconds; - /* Start session start timer */ - TimerSetValue(&SessionStartTimer, timeToSessionStart * 1000); - TimerStart(&SessionStartTimer); - - MW_LOG(TS_OFF, VLEVEL_M, "Time2SessionStart: %d ms\r\n", timeToSessionStart * 1000); - } - else - { - /* Session start time before current device time */ - status |= 0x20; - } + MW_LOG(TS_OFF, VLEVEL_M, "ID : %d\r\n", McSessionData[id].McGroupData.IdHeader.Fields.McGroupId); + MW_LOG(TS_OFF, VLEVEL_M, "McAddr : %08X\r\n", McSessionData[id].McGroupData.McAddr); + MW_LOG(TS_OFF, VLEVEL_M, "McKey : %02X", McSessionData[id].McGroupData.McKeyEncrypted[0]); + for ( int i = 1; i < 16; i++ ) + { + MW_LOG(TS_OFF, VLEVEL_M, "-%02X", McSessionData[id].McGroupData.McKeyEncrypted[i]); + } + MW_LOG(TS_OFF, VLEVEL_M, "\r\n"); + MW_LOG(TS_OFF, VLEVEL_M, "McFCountMin : %u\r\n", McSessionData[id].McGroupData.McFCountMin); + MW_LOG(TS_OFF, VLEVEL_M, "McFCountMax : %u\r\n", McSessionData[id].McGroupData.McFCountMax); + MW_LOG(TS_OFF, VLEVEL_M, "SessionTime : %u\r\n", McSessionData[id].SessionTime); + MW_LOG(TS_OFF, VLEVEL_M, "SessionTimeT: %d s\r\n", (1 << McSessionData[id].SessionTimeout)); + MW_LOG(TS_OFF, VLEVEL_M, "Rx Freq : %u\r\n", McSessionData[id].RxParams.ClassC.Frequency); + MW_LOG(TS_OFF, VLEVEL_M, "Rx DR : DR_%d\r\n", McSessionData[id].RxParams.ClassC.Datarate); } - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = status; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 0) & 0xFF; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 8) & 0xFF; - LmhpRemoteMcastSetupState.DataBuffer[dataBufferIndex++] = (timeToSessionStart >> 16) & 0xFF; - break; - } - case REMOTE_MCAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ: - { - /* implement command prosessing and handling */ - break; - } - default: - { - break; - } - } - } - - if (dataBufferIndex != 0) - { - /* Answer commands */ - LmHandlerAppData_t appData = - { - .Buffer = LmhpRemoteMcastSetupState.DataBuffer, - .BufferSize = dataBufferIndex, - .Port = REMOTE_MCAST_SETUP_PORT - }; - - bool current_dutycycle; - LmHandlerGetDutyCycleEnable(¤t_dutycycle); - - /* force Duty Cycle OFF to this Send */ - LmHandlerSetDutyCycleEnable(false); - LmhpRemoteMcastSetupPackage.OnSendRequest(&appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, NULL, true); - - /* restore initial Duty Cycle */ - LmHandlerSetDutyCycleEnable(current_dutycycle); - - if (id != 0xFF && id < LORAMAC_MAX_MC_CTX) - { - MW_LOG(TS_OFF, VLEVEL_M, "ID : %d\r\n", McSessionData[id].McGroupData.IdHeader.Fields.McGroupId); - MW_LOG(TS_OFF, VLEVEL_M, "McAddr : %08X\r\n", McSessionData[id].McGroupData.McAddr); - MW_LOG(TS_OFF, VLEVEL_M, "McKey : %02X", McSessionData[id].McGroupData.McKeyEncrypted[0]); - for (int i = 1; i < 16; i++) - { - MW_LOG(TS_OFF, VLEVEL_M, "-%02X", McSessionData[id].McGroupData.McKeyEncrypted[i]); - } - MW_LOG(TS_OFF, VLEVEL_M, "\r\n"); - MW_LOG(TS_OFF, VLEVEL_M, "McFCountMin : %u\r\n", McSessionData[id].McGroupData.McFCountMin); - MW_LOG(TS_OFF, VLEVEL_M, "McFCountMax : %u\r\n", McSessionData[id].McGroupData.McFCountMax); - MW_LOG(TS_OFF, VLEVEL_M, "SessionTime : %u\r\n", McSessionData[id].SessionTime); - MW_LOG(TS_OFF, VLEVEL_M, "SessionTimeT: %d s\r\n", (1 << McSessionData[id].SessionTimeout)); - MW_LOG(TS_OFF, VLEVEL_M, "Rx Freq : %u\r\n", McSessionData[id].RxParams.ClassC.Frequency); - MW_LOG(TS_OFF, VLEVEL_M, "Rx DR : DR_%d\r\n", McSessionData[id].RxParams.ClassC.Datarate); } - } } -static void OnSessionStartTimer(void *context) +static void OnSessionStartTimer( void *context ) { - TimerStop(&SessionStartTimer); - LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_START; - LmhpRemoteMcastSetupProcess(); + TimerStop( &SessionStartTimer ); + LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_START; + LmhpRemoteMcastSetupPackage.OnPackageProcessEvent(); } -static void OnSessionStopTimer(void *context) +static void OnSessionStopTimer( void *context ) { - TimerStop(&SessionStopTimer); - LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_STOP; + TimerStop( &SessionStopTimer ); + LmhpRemoteMcastSetupState.SessionState = REMOTE_MCAST_SETUP_SESSION_STATE_STOP; + LmhpRemoteMcastSetupPackage.OnPackageProcessEvent(); } diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.h index 35801e9f..db013871 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/Packages/LmhpRemoteMcastSetup.h @@ -19,27 +19,13 @@ * * \author Miguel Luis ( Semtech ) */ -/** - ****************************************************************************** - * - * Portions COPYRIGHT 2020 STMicroelectronics - * - * @file LmhpRemoteMcastSetup.h - * @author MCD Application Team - * @brief Header for Remote Multicast Package module - ****************************************************************************** - */ #ifndef __LMHP_REMOTE_MCAST_SETUP_H__ #define __LMHP_REMOTE_MCAST_SETUP_H__ -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ +#include "LoRaMac.h" +#include "LmHandlerTypes.h" #include "LmhPackage.h" -/* Exported defines ----------------------------------------------------------*/ /*! * Remote multicast setup package identifier. * @@ -47,16 +33,6 @@ extern "C" { */ #define PACKAGE_ID_REMOTE_MCAST_SETUP 2 -/* Exported constants --------------------------------------------------------*/ -/* Exported types ------------------------------------------------------------*/ -/* External variables --------------------------------------------------------*/ -/* Exported macros -----------------------------------------------------------*/ -/* Exported functions ------------------------------------------------------- */ -LmhPackage_t *LmhpRemoteMcastSetupPackageFactory(void); - - -#ifdef __cplusplus -} -#endif +LmhPackage_t *LmhpRemoteMcastSetupPackageFactory( void ); -#endif /* __LMHP_REMOTE_MCAST_SETUP_H__ */ +#endif // __LMHP_REMOTE_MCAST_SETUP_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/LmHandler/lorawan_version.h b/Middlewares/Third_Party/LoRaWAN/LmHandler/lorawan_version.h index c0d9054b..05c62608 100644 --- a/Middlewares/Third_Party/LoRaWAN/LmHandler/lorawan_version.h +++ b/Middlewares/Third_Party/LoRaWAN/LmHandler/lorawan_version.h @@ -30,8 +30,8 @@ /* Exported constants --------------------------------------------------------*/ #define __LORAWAN_VERSION_MAIN (0x02U) /*!< [31:24] main version */ -#define __LORAWAN_VERSION_SUB1 (0x02U) /*!< [23:16] sub1 version */ -#define __LORAWAN_VERSION_SUB2 (0x01U) /*!< [15:8] sub2 version */ +#define __LORAWAN_VERSION_SUB1 (0x03U) /*!< [23:16] sub1 version */ +#define __LORAWAN_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */ #define __LORAWAN_VERSION_RC (0x00U) /*!< [7:0] release candidate */ #define __LORAWAN_MAIN_SHIFT 24 diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.c b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.c index 5924faad..49883ad4 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.c @@ -40,7 +40,6 @@ * @brief LoRa MAC layer implementation ****************************************************************************** */ -/* Includes ------------------------------------------------------------------*/ #include "utilities.h" #include "Region.h" #include "LoRaMacClassB.h" @@ -55,12 +54,11 @@ #include "LoRaMacCommands.h" #include "LoRaMacAdr.h" #include "LoRaMacSerializer.h" +#include "radio.h" #include "LoRaMac.h" #include "mw_log_conf.h" -/* Private macro -------------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ #ifndef LORAMAC_VERSION /*! * LoRaWAN version definition. @@ -73,11 +71,6 @@ */ #define LORAMAC_PHY_MAXPAYLOAD 255 -/*! - * Maximum MAC commands buffer size - */ -#define LORA_MAC_COMMAND_MAX_LENGTH 128 - /*! * Maximum length of the fOpts field */ @@ -98,7 +91,6 @@ */ #define BACKOFF_DC_24_HOURS 10000 -/* Private typedef -----------------------------------------------------------*/ /*! * LoRaMac internal states */ @@ -123,101 +115,6 @@ typedef enum eLoRaMacRequestHandling LORAMAC_REQUEST_HANDLING_ON = !LORAMAC_REQUEST_HANDLING_OFF }LoRaMacRequestHandling_t; -typedef struct sLoRaMacNvmCtx -{ - /* - * LoRaMac region. - */ - LoRaMacRegion_t Region; - /* - * LoRaMac default parameters - */ - LoRaMacParams_t MacParamsDefaults; - /* - * Network ID ( 3 bytes ) - */ - uint32_t NetID; - /* - * Mote Address - */ - uint32_t DevAddr; - /*! - * Multicast channel list - */ - MulticastCtx_t MulticastChannelList[LORAMAC_MAX_MC_CTX]; - /* - * Actual device class - */ - DeviceClass_t DeviceClass; - /* - * Indicates if the node is connected to - * a private or public network - */ - bool PublicNetwork; - /* - * LoRaMac ADR control status - */ - bool AdrCtrlOn; - /* - * Counts the number of missed ADR acknowledgements - */ - uint32_t AdrAckCounter; - - /* - * LoRaMac parameters - */ - LoRaMacParams_t MacParams; - /* - * Maximum duty cycle - * \remark Possibility to shutdown the device. - */ - uint8_t MaxDCycle; - /* - * Enables/Disables duty cycle management (Test only) - */ - bool DutyCycleOn; - /* - * Holds the current rx window slot - */ - bool RepeaterSupport; - /* - * Buffer containing the MAC layer commands - */ - uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; - /* - * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates - * if the ACK bit must be set for the next transmission - */ - bool SrvAckRequested; - /* - * Aggregated duty cycle management - */ - uint16_t AggregatedDCycle; - /* - * Aggregated duty cycle management - */ - TimerTime_t LastTxDoneTime; - TimerTime_t AggregatedTimeOff; - /* - * Stores the time at LoRaMac initialization. - * - * \remark Used for the BACKOFF_DC computation. - */ - SysTime_t InitializationTime; - /* - * Current LoRaWAN Version - */ - Version_t Version; - /* - * End-Device network activation - */ - ActivationType_t NetworkActivation; - /*! - * Last received Message integrity Code (MIC) - */ - uint32_t LastRxMic; -}LoRaMacNvmCtx_t; - typedef struct sLoRaMacCtx { /* @@ -341,6 +238,10 @@ typedef struct sLoRaMacCtx * Structure to hold MLME indication data. */ MlmeIndication_t MlmeIndication; + /* + * Structure to hold global Rx Status. + */ + LoRaMacRxStatus_t RxStatus; /* * Holds the current rx window slot */ @@ -354,15 +255,22 @@ typedef struct sLoRaMacCtx */ LoRaMacRequestHandling_t AllowRequests; /* - * Non-volatile module context structure - */ - LoRaMacNvmCtx_t* NvmCtx; - /* * Duty cycle wait time */ TimerTime_t DutyCycleWaitTime; + /* + * Buffer containing the MAC layer commands + */ + uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; }LoRaMacCtx_t; +/* + * Module context. + */ +static LoRaMacCtx_t MacCtx; + +static LoRaMacNvmData_t Nvm; + /*! * Defines the LoRaMac radio events status */ @@ -379,48 +287,11 @@ typedef union uLoRaMacRadioEvents }Events; }LoRaMacRadioEvents_t; -/*! - * Structure used to store the radio Tx event data - */ -struct -{ - TimerTime_t CurTime; -}TxDoneParams; - -/*! - * Structure used to store the radio Rx event data - */ -struct -{ - TimerTime_t LastRxDone; - uint8_t *Payload; - uint16_t Size; - int16_t Rssi; - int8_t Snr; -}RxDoneParams; - -/* Private variables ---------------------------------------------------------*/ -/* - * Module context. - */ -static LoRaMacCtx_t MacCtx; - -/* - * Non-volatile module context. - */ -static LoRaMacNvmCtx_t NvmMacCtx; - -/* - * List of module contexts. - */ -static LoRaMacCtxs_t Contexts; - /*! * LoRaMac radio events status */ LoRaMacRadioEvents_t LoRaMacRadioEvents = { .Value = 0 }; -/* Private function prototypes -----------------------------------------------*/ /*! * \brief Function to be executed on Radio Tx Done event */ @@ -539,6 +410,7 @@ static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsL */ static void ProcessMacCommands( uint8_t* payload, uint8_t macIndex, uint8_t commandsSize, int8_t snr, LoRaMacRxSlot_t rxSlot ); +/* ST_WORKAROUND_BEGIN: Update Send request with new input parameter to allow delayed tx */ /*! * \brief LoRaMAC layer generic send frame * @@ -549,6 +421,7 @@ static void ProcessMacCommands( uint8_t* payload, uint8_t macIndex, uint8_t comm * \retval status Status of the operation. */ static LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuffer, uint16_t fBufferSize, bool allowDelayedTx ); +/* ST_WORKAROUND_END */ /*! * \brief LoRaMAC layer send join/rejoin request @@ -660,7 +533,7 @@ static void OpenContinuousRxCWindow( void ); * * \retval void Points to a structure containing all contexts */ -static LoRaMacCtxs_t* GetCtxs( void ); +static LoRaMacNvmData_t* GetNvmData( void ); /*! * \brief Restoring of internal module contexts @@ -673,7 +546,7 @@ static LoRaMacCtxs_t* GetCtxs( void ); * \ref LORAMAC_STATUS_OK, * \ref LORAMAC_STATUS_PARAMETER_INVALID, */ -static LoRaMacStatus_t RestoreCtxs( LoRaMacCtxs_t* contexts ); +static LoRaMacStatus_t RestoreNvmData( LoRaMacNvmData_t* contexts ); /*! * \brief Determines the frame type @@ -710,6 +583,11 @@ static bool CheckRetransConfirmedUplink( void ); */ static bool StopRetransmission( void ); +/*! + * \brief Calls the callback to indicate that a context changed + */ +static void CallNvmDataChangeCallback( uint16_t notifyFlags ); + /*! * \brief Handles the ACK retries algorithm. * Increments the re-tries counter up until the specified number of @@ -724,46 +602,6 @@ static void AckTimeoutRetriesProcess( void ); */ static void AckTimeoutRetriesFinalize( void ); -/*! - * \brief Calls the callback to indicate that a context changed - */ -static void CallNvmCtxCallback( LoRaMacNvmCtxModule_t module ); - -/*! - * \brief MAC NVM Context has been changed - */ -static void EventMacNvmCtxChanged( void ); - -/*! - * \brief Region NVM Context has been changed - */ -static void EventRegionNvmCtxChanged( void ); - -/*! - * \brief Crypto NVM Context has been changed - */ -static void EventCryptoNvmCtxChanged( void ); - -/*! - * \brief Secure Element NVM Context has been changed - */ -static void EventSecureElementNvmCtxChanged( void ); - -/*! - * \brief MAC commands module nvm context has been changed - */ -static void EventCommandsNvmCtxChanged( void ); - -/*! - * \brief Class B module nvm context has been changed - */ -static void EventClassBNvmCtxChanged( void ); - -/*! - * \brief Confirm Queue module nvm context has been changed - */ -static void EventConfirmQueueNvmCtxChanged( void ); - /*! * \brief Verifies if a request is pending currently * @@ -811,7 +649,33 @@ static void LoRaMacHandleRequestEvents( void ); */ static void LoRaMacHandleIndicationEvents( void ); -/* Private functions ---------------------------------------------------------*/ +/*! + * \brief This function handles callback events for NVM updates + * + * \param [IN] nvmData Data structure containing NVM data. + */ +static void LoRaMacHandleNvm( LoRaMacNvmData_t* nvmData ); + +/*! + * Structure used to store the radio Tx event data + */ +struct +{ + TimerTime_t CurTime; +}TxDoneParams; + +/*! + * Structure used to store the radio Rx event data + */ +struct +{ + TimerTime_t LastRxDone; + uint8_t *Payload; + uint16_t Size; + int16_t Rssi; + int8_t Snr; +}RxDoneParams; + static void OnRadioTxDone( void ) { TxDoneParams.CurTime = TimerGetCurrentTime( ); @@ -877,7 +741,7 @@ static void OnRadioRxTimeout( void ) static void UpdateRxSlotIdleState( void ) { - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { MacCtx.RxSlot = RX_SLOT_NONE; } @@ -893,7 +757,7 @@ static void ProcessRadioTxDone( void ) PhyParam_t phyParam; SetBandTxDoneParams_t txDone; - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { Radio.Sleep( ); } @@ -903,29 +767,29 @@ static void ProcessRadioTxDone( void ) TimerSetValue( &MacCtx.RxWindowTimer2, MacCtx.RxWindow2Delay ); TimerStart( &MacCtx.RxWindowTimer2 ); - if( ( MacCtx.NvmCtx->DeviceClass == CLASS_C ) || ( MacCtx.NodeAckRequested == true ) ) + if( ( Nvm.MacGroup2.DeviceClass == CLASS_C ) || ( MacCtx.NodeAckRequested == true ) ) { getPhy.Attribute = PHY_ACK_TIMEOUT; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); TimerSetValue( &MacCtx.AckTimeoutTimer, MacCtx.RxWindow2Delay + phyParam.Value ); TimerStart( &MacCtx.AckTimeoutTimer ); } // Update Aggregated last tx done time - MacCtx.NvmCtx->LastTxDoneTime = TxDoneParams.CurTime; + Nvm.MacGroup1.LastTxDoneTime = TxDoneParams.CurTime; // Update last tx done time for the current channel txDone.Channel = MacCtx.Channel; txDone.LastTxDoneTime = TxDoneParams.CurTime; - txDone.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), MacCtx.NvmCtx->InitializationTime ); + txDone.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), Nvm.MacGroup2.InitializationTime ); txDone.LastTxAirTime = MacCtx.TxTimeOnAir; txDone.Joined = true; - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { txDone.Joined = false; } - RegionSetBandTxDone( MacCtx.NvmCtx->Region, &txDone ); + RegionSetBandTxDone( Nvm.MacGroup2.Region, &txDone ); if( MacCtx.NodeAckRequested == false ) { @@ -966,15 +830,15 @@ static void ProcessRadioRxDone( void ) uint8_t pktHeaderLen = 0; uint32_t downLinkCounter = 0; - uint32_t address = MacCtx.NvmCtx->DevAddr; + uint32_t address = Nvm.MacGroup2.DevAddr; uint8_t multicast = 0; AddressIdentifier_t addrID = UNICAST_DEV_ADDR; FCntIdentifier_t fCntID; MacCtx.McpsConfirm.AckReceived = false; - MacCtx.McpsIndication.Rssi = rssi; - MacCtx.McpsIndication.Snr = snr; - MacCtx.McpsIndication.RxSlot = MacCtx.RxSlot; + MacCtx.RxStatus.Rssi = rssi; + MacCtx.RxStatus.Snr = snr; + MacCtx.RxStatus.RxSlot = MacCtx.RxSlot; MacCtx.McpsIndication.Port = 0; MacCtx.McpsIndication.Multicast = 0; MacCtx.McpsIndication.FramePending = 0; @@ -998,19 +862,19 @@ static void ProcessRadioRxDone( void ) return; } // Check if we expect a ping or a multicast slot. - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { if( LoRaMacClassBIsPingExpected( ) == true ) { LoRaMacClassBSetPingSlotState( PINGSLOT_STATE_CALC_PING_OFFSET ); LoRaMacClassBPingSlotTimerEvent( NULL ); - MacCtx.McpsIndication.RxSlot = RX_SLOT_WIN_CLASS_B_PING_SLOT; + MacCtx.RxStatus.RxSlot = RX_SLOT_WIN_CLASS_B_PING_SLOT; } else if( LoRaMacClassBIsMulticastExpected( ) == true ) { LoRaMacClassBSetMulticastSlotState( PINGSLOT_STATE_CALC_PING_OFFSET ); LoRaMacClassBMulticastSlotTimerEvent( NULL ); - MacCtx.McpsIndication.RxSlot = RX_SLOT_WIN_CLASS_B_MULTICAST_SLOT; + MacCtx.RxStatus.RxSlot = RX_SLOT_WIN_CLASS_B_MULTICAST_SLOT; } } @@ -1030,7 +894,7 @@ static void ProcessRadioRxDone( void ) macMsgJoinAccept.BufSize = size; // Abort in case if the device isn't joined yet and no rejoin request is ongoing. - if( MacCtx.NvmCtx->NetworkActivation != ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation != ACTIVATION_TYPE_NONE ) { MacCtx.McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); @@ -1041,37 +905,37 @@ static void ProcessRadioRxDone( void ) if( LORAMAC_CRYPTO_SUCCESS == macCryptoStatus ) { // Network ID - MacCtx.NvmCtx->NetID = ( uint32_t ) macMsgJoinAccept.NetID[0]; - MacCtx.NvmCtx->NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[1] << 8 ); - MacCtx.NvmCtx->NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[2] << 16 ); + Nvm.MacGroup2.NetID = ( uint32_t ) macMsgJoinAccept.NetID[0]; + Nvm.MacGroup2.NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[1] << 8 ); + Nvm.MacGroup2.NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[2] << 16 ); // Device Address - MacCtx.NvmCtx->DevAddr = macMsgJoinAccept.DevAddr; + Nvm.MacGroup2.DevAddr = macMsgJoinAccept.DevAddr; // DLSettings - MacCtx.NvmCtx->MacParams.Rx1DrOffset = macMsgJoinAccept.DLSettings.Bits.RX1DRoffset; - MacCtx.NvmCtx->MacParams.Rx2Channel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; + Nvm.MacGroup2.MacParams.Rx1DrOffset = macMsgJoinAccept.DLSettings.Bits.RX1DRoffset; + Nvm.MacGroup2.MacParams.Rx2Channel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; + Nvm.MacGroup2.MacParams.RxCChannel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; // RxDelay - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = macMsgJoinAccept.RxDelay; - if( MacCtx.NvmCtx->MacParams.ReceiveDelay1 == 0 ) + Nvm.MacGroup2.MacParams.ReceiveDelay1 = macMsgJoinAccept.RxDelay; + if( Nvm.MacGroup2.MacParams.ReceiveDelay1 == 0 ) { - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = 1; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = 1; } - MacCtx.NvmCtx->MacParams.ReceiveDelay1 *= 1000; - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = MacCtx.NvmCtx->MacParams.ReceiveDelay1 + 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay1 *= 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = Nvm.MacGroup2.MacParams.ReceiveDelay1 + 1000; - MacCtx.NvmCtx->Version.Fields.Minor = 0; + Nvm.MacGroup2.Version.Fields.Minor = 0; // Apply CF list applyCFList.Payload = macMsgJoinAccept.CFList; // Size of the regular payload is 12. Plus 1 byte MHDR and 4 bytes MIC applyCFList.Size = size - 17; - RegionApplyCFList( MacCtx.NvmCtx->Region, &applyCFList ); + RegionApplyCFList( Nvm.MacGroup2.Region, &applyCFList ); - MacCtx.NvmCtx->NetworkActivation = ACTIVATION_TYPE_OTAA; + Nvm.MacGroup2.NetworkActivation = ACTIVATION_TYPE_OTAA; // MLME handling if( LoRaMacConfirmQueueIsCmdActive( MLME_JOIN ) == true ) @@ -1087,23 +951,26 @@ static void ProcessRadioRxDone( void ) LoRaMacConfirmQueueSetStatus( LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL, MLME_JOIN ); } } + MacCtx.MacFlags.Bits.MlmeInd = 1; break; case FRAME_TYPE_DATA_CONFIRMED_DOWN: MacCtx.McpsIndication.McpsIndication = MCPS_CONFIRMED; // Intentional fall through case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: // Check if the received payload size is valid - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; getPhy.Datarate = MacCtx.McpsIndication.RxDatarate; getPhy.Attribute = PHY_MAX_PAYLOAD; + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ // Get the maximum payload length - if( MacCtx.NvmCtx->RepeaterSupport == true ) + if( Nvm.MacGroup2.MacParams.RepeaterSupport == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } + /* ST_WORKAROUND_END */ - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); if( ( MAX( 0, ( int16_t )( ( int16_t ) size - ( int16_t ) LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ) ) > ( int16_t )phyParam.Value ) || ( size < LORAMAC_FRAME_PAYLOAD_MIN_SIZE ) ) { @@ -1139,16 +1006,16 @@ static void ProcessRadioRxDone( void ) downLinkCounter = 0; for( uint8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - if( ( MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.Address == macMsgData.FHDR.DevAddr ) && - ( MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.IsEnabled == true ) ) + if( ( Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.Address == macMsgData.FHDR.DevAddr ) && + ( Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.IsEnabled == true ) ) { multicast = 1; - addrID = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.GroupID; - downLinkCounter = *( MacCtx.NvmCtx->MulticastChannelList[i].DownLinkCounter ); - address = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.Address; - if( MacCtx.NvmCtx->DeviceClass == CLASS_C ) + addrID = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.GroupID; + downLinkCounter = *( Nvm.MacGroup2.MulticastChannelList[i].DownLinkCounter ); + address = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.Address; + if( Nvm.MacGroup2.DeviceClass == CLASS_C ) { - MacCtx.McpsIndication.RxSlot = RX_SLOT_WIN_CLASS_C_MULTICAST; + MacCtx.RxStatus.RxSlot = RX_SLOT_WIN_CLASS_C_MULTICAST; } break; } @@ -1166,19 +1033,19 @@ static void ProcessRadioRxDone( void ) // Get maximum allowed counter difference getPhy.Attribute = PHY_MAX_FCNT_GAP; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); // Get downlink frame counter value - macCryptoStatus = GetFCntDown( addrID, fType, &macMsgData, MacCtx.NvmCtx->Version, phyParam.Value, &fCntID, &downLinkCounter ); + macCryptoStatus = GetFCntDown( addrID, fType, &macMsgData, Nvm.MacGroup2.Version, phyParam.Value, &fCntID, &downLinkCounter ); if( macCryptoStatus != LORAMAC_CRYPTO_SUCCESS ) { if( macCryptoStatus == LORAMAC_CRYPTO_FAIL_FCNT_DUPLICATED ) { // Catch the case of repeated downlink frame counter MacCtx.McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - if( ( MacCtx.NvmCtx->Version.Fields.Minor == 0 ) && ( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) && ( MacCtx.NvmCtx->LastRxMic == macMsgData.MIC ) ) + if( ( Nvm.MacGroup2.Version.Fields.Minor == 0 ) && ( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) && ( Nvm.MacGroup1.LastRxMic == macMsgData.MIC ) ) { - MacCtx.NvmCtx->SrvAckRequested = true; + Nvm.MacGroup1.SrvAckRequested = true; } } else if( macCryptoStatus == LORAMAC_CRYPTO_FAIL_MAX_GAP_FCNT ) @@ -1226,10 +1093,10 @@ static void ProcessRadioRxDone( void ) MacCtx.McpsConfirm.AckReceived = macMsgData.FHDR.FCtrl.Bits.Ack; // Reset ADR ACK Counter only, when RX1 or RX2 slot - if( ( MacCtx.McpsIndication.RxSlot == RX_SLOT_WIN_1 ) || - ( MacCtx.McpsIndication.RxSlot == RX_SLOT_WIN_2 ) ) + if( ( MacCtx.RxStatus.RxSlot == RX_SLOT_WIN_1 ) || + ( MacCtx.RxStatus.RxSlot == RX_SLOT_WIN_2 ) ) { - MacCtx.NvmCtx->AdrAckCounter = 0; + Nvm.MacGroup1.AdrAckCounter = 0; } // MCPS Indication and ack requested handling @@ -1241,21 +1108,21 @@ static void ProcessRadioRxDone( void ) { if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) { - MacCtx.NvmCtx->SrvAckRequested = true; - if( MacCtx.NvmCtx->Version.Fields.Minor == 0 ) + Nvm.MacGroup1.SrvAckRequested = true; + if( Nvm.MacGroup2.Version.Fields.Minor == 0 ) { - MacCtx.NvmCtx->LastRxMic = macMsgData.MIC; + Nvm.MacGroup1.LastRxMic = macMsgData.MIC; } MacCtx.McpsIndication.McpsIndication = MCPS_CONFIRMED; } else { - MacCtx.NvmCtx->SrvAckRequested = false; + Nvm.MacGroup1.SrvAckRequested = false; MacCtx.McpsIndication.McpsIndication = MCPS_UNCONFIRMED; } } - RemoveMacCommands( MacCtx.McpsIndication.RxSlot, macMsgData.FHDR.FCtrl, MacCtx.McpsConfirm.McpsRequest ); + RemoveMacCommands( MacCtx.RxStatus.RxSlot, macMsgData.FHDR.FCtrl, MacCtx.McpsConfirm.McpsRequest ); switch( fType ) { @@ -1268,7 +1135,7 @@ static void ProcessRadioRxDone( void ) */ // Decode MAC commands in FOpts field - ProcessMacCommands( macMsgData.FHDR.FOpts, 0, macMsgData.FHDR.FCtrl.Bits.FOptsLen, snr, MacCtx.McpsIndication.RxSlot ); + ProcessMacCommands( macMsgData.FHDR.FOpts, 0, macMsgData.FHDR.FCtrl.Bits.FOptsLen, snr, MacCtx.RxStatus.RxSlot ); MacCtx.McpsIndication.Port = macMsgData.FPort; MacCtx.McpsIndication.Buffer = macMsgData.FRMPayload; MacCtx.McpsIndication.BufferSize = macMsgData.FRMPayloadSize; @@ -1284,7 +1151,7 @@ static void ProcessRadioRxDone( void ) */ // Decode MAC commands in FOpts field - ProcessMacCommands( macMsgData.FHDR.FOpts, 0, macMsgData.FHDR.FCtrl.Bits.FOptsLen, snr, MacCtx.McpsIndication.RxSlot ); + ProcessMacCommands( macMsgData.FHDR.FOpts, 0, macMsgData.FHDR.FCtrl.Bits.FOptsLen, snr, MacCtx.RxStatus.RxSlot ); MacCtx.McpsIndication.Port = macMsgData.FPort; break; } @@ -1297,7 +1164,7 @@ static void ProcessRadioRxDone( void ) */ // Decode MAC commands in FRMPayload - ProcessMacCommands( macMsgData.FRMPayload, 0, macMsgData.FRMPayloadSize, snr, MacCtx.McpsIndication.RxSlot ); + ProcessMacCommands( macMsgData.FRMPayload, 0, macMsgData.FRMPayloadSize, snr, MacCtx.RxStatus.RxSlot ); MacCtx.McpsIndication.Port = macMsgData.FPort; break; } @@ -1353,7 +1220,7 @@ static void ProcessRadioRxDone( void ) } else { - if( MacCtx.NvmCtx->DeviceClass == CLASS_C ) + if( Nvm.MacGroup2.DeviceClass == CLASS_C ) { OnAckTimeoutTimerEvent( NULL ); } @@ -1365,7 +1232,7 @@ static void ProcessRadioRxDone( void ) static void ProcessRadioTxTimeout( void ) { - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { Radio.Sleep( ); } @@ -1384,7 +1251,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat { bool classBRx = false; - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { Radio.Sleep( ); } @@ -1395,7 +1262,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat LoRaMacClassBBeaconTimerEvent( NULL ); classBRx = true; } - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { if( LoRaMacClassBIsPingExpected( ) == true ) { @@ -1421,7 +1288,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat } LoRaMacConfirmQueueSetStatusCmn( rx1EventInfoStatus ); - if( TimerGetElapsedTime( MacCtx.NvmCtx->LastTxDoneTime ) >= MacCtx.RxWindow2Delay ) + if( TimerGetElapsedTime( Nvm.MacGroup1.LastTxDoneTime ) >= MacCtx.RxWindow2Delay ) { TimerStop( &MacCtx.RxWindowTimer2 ); MacCtx.MacFlags.Bits.MacDone = 1; @@ -1435,7 +1302,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat } LoRaMacConfirmQueueSetStatusCmn( rx2EventInfoStatus ); - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { MacCtx.MacFlags.Bits.MacDone = 1; } @@ -1489,6 +1356,17 @@ static void LoRaMacHandleIrqEvents( void ) } } +bool LoRaMacIsBusy( void ) +{ + if( ( MacCtx.MacState == LORAMAC_IDLE ) && + ( MacCtx.AllowRequests == LORAMAC_REQUEST_HANDLING_ON ) ) + { + return false; + } + return true; +} + + static void LoRaMacEnableRequests( LoRaMacRequestHandling_t requestState ) { MacCtx.AllowRequests = requestState; @@ -1559,7 +1437,7 @@ static void LoRaMacHandleIndicationEvents( void ) if( MacCtx.MacFlags.Bits.MlmeInd == 1 ) { MacCtx.MacFlags.Bits.MlmeInd = 0; - MacCtx.MacPrimitives->MacMlmeIndication( &MacCtx.MlmeIndication ); + MacCtx.MacPrimitives->MacMlmeIndication( &MacCtx.MlmeIndication, &MacCtx.RxStatus ); } if( MacCtx.MacFlags.Bits.MlmeSchedUplinkInd == 1 ) @@ -1568,7 +1446,7 @@ static void LoRaMacHandleIndicationEvents( void ) schduleUplinkIndication.MlmeIndication = MLME_SCHEDULE_UPLINK; schduleUplinkIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK; - MacCtx.MacPrimitives->MacMlmeIndication( &schduleUplinkIndication ); + MacCtx.MacPrimitives->MacMlmeIndication( &schduleUplinkIndication, &MacCtx.RxStatus ); MacCtx.MacFlags.Bits.MlmeSchedUplinkInd = 0; } @@ -1576,7 +1454,7 @@ static void LoRaMacHandleIndicationEvents( void ) if( MacCtx.MacFlags.Bits.McpsInd == 1 ) { MacCtx.MacFlags.Bits.McpsInd = 0; - MacCtx.MacPrimitives->MacMcpsIndication( &MacCtx.McpsIndication ); + MacCtx.MacPrimitives->MacMcpsIndication( &MacCtx.McpsIndication, &MacCtx.RxStatus ); } } @@ -1599,7 +1477,7 @@ static void LoRaMacHandleMcpsRequest( void ) { stopRetransmission = CheckRetransConfirmedUplink( ); - if( MacCtx.NvmCtx->Version.Fields.Minor == 0 ) + if( Nvm.MacGroup2.Version.Fields.Minor == 0 ) { if( stopRetransmission == false ) { @@ -1679,6 +1557,118 @@ static void LoRaMacCheckForRxAbort( void ) } } +static void LoRaMacHandleNvm( LoRaMacNvmData_t* nvmData ) +{ + uint32_t crc = 0; + uint16_t notifyFlags = LORAMAC_NVM_NOTIFY_FLAG_NONE; + + if( MacCtx.MacState != LORAMAC_IDLE ) + { + return; + } + + // Crypto + crc = Crc32( ( uint8_t* ) &nvmData->Crypto, sizeof( nvmData->Crypto ) - + sizeof( nvmData->Crypto.Crc32 ) ); + if( crc != nvmData->Crypto.Crc32 ) + { + nvmData->Crypto.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_CRYPTO; + } + + // MacGroup1 + crc = Crc32( ( uint8_t* ) &nvmData->MacGroup1, sizeof( nvmData->MacGroup1 ) - + sizeof( nvmData->MacGroup1.Crc32 ) ); + if( crc != nvmData->MacGroup1.Crc32 ) + { + nvmData->MacGroup1.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1; + } + + // MacGroup2 + crc = Crc32( ( uint8_t* ) &nvmData->MacGroup2, sizeof( nvmData->MacGroup2 ) - + sizeof( nvmData->MacGroup2.Crc32 ) ); + if( crc != nvmData->MacGroup2.Crc32 ) + { + nvmData->MacGroup2.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2; + } + + // Secure Element + crc = Crc32( ( uint8_t* ) &nvmData->SecureElement, sizeof( nvmData->SecureElement ) - + sizeof( nvmData->SecureElement.Crc32 ) ); + if( crc != nvmData->SecureElement.Crc32 ) + { + nvmData->SecureElement.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT; + } + + // Region + crc = Crc32( ( uint8_t* ) &nvmData->RegionGroup1, sizeof( nvmData->RegionGroup1 ) - + sizeof( nvmData->RegionGroup1.Crc32 ) ); + if( crc != nvmData->RegionGroup1.Crc32 ) + { + nvmData->RegionGroup1.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1; + } + + crc = Crc32( ( uint8_t* ) &nvmData->RegionGroup2, sizeof( nvmData->RegionGroup2 ) - + sizeof( nvmData->RegionGroup2.Crc32 ) ); + if( crc != nvmData->RegionGroup2.Crc32 ) + { + nvmData->RegionGroup2.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2; + } + + // ClassB + crc = Crc32( ( uint8_t* ) &nvmData->ClassB, sizeof( nvmData->ClassB ) - + sizeof( nvmData->ClassB.Crc32 ) ); + if( crc != nvmData->ClassB.Crc32 ) + { + nvmData->ClassB.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_CLASS_B; + } + + CallNvmDataChangeCallback( notifyFlags ); +} + + +void LoRaMacProcess( void ) +{ + uint8_t noTx = false; + + LoRaMacHandleIrqEvents( ); + LoRaMacClassBProcess( ); + + // MAC proceeded a state and is ready to check + if( MacCtx.MacFlags.Bits.MacDone == 1 ) + { + LoRaMacEnableRequests( LORAMAC_REQUEST_HANDLING_OFF ); + LoRaMacCheckForRxAbort( ); + + // An error occurs during transmitting + if( IsRequestPending( ) > 0 ) + { + noTx |= LoRaMacCheckForBeaconAcquisition( ); + } + + if( noTx == 0x00 ) + { + LoRaMacHandleMlmeRequest( ); + LoRaMacHandleMcpsRequest( ); + } + LoRaMacHandleRequestEvents( ); + LoRaMacHandleScheduleUplinkEvent( ); + LoRaMacHandleNvm( &Nvm ); + LoRaMacEnableRequests( LORAMAC_REQUEST_HANDLING_ON ); + } + LoRaMacHandleIndicationEvents( ); + if( MacCtx.RxSlot == RX_SLOT_WIN_CLASS_C ) + { + OpenContinuousRxCWindow( ); + } +} + static void OnTxDelayedTimerEvent( void* context ) { TimerStop( &MacCtx.TxDelayedTimer ); @@ -1695,7 +1685,7 @@ static void OnTxDelayedTimerEvent( void* context ) default: { // Stop retransmission attempt - MacCtx.McpsConfirm.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; + MacCtx.McpsConfirm.Datarate = Nvm.MacGroup1.ChannelsDatarate; MacCtx.McpsConfirm.NbRetries = MacCtx.AckTimeoutRetriesCounter; MacCtx.McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; LoRaMacConfirmQueueSetStatusCmn( LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR ); @@ -1708,9 +1698,9 @@ static void OnTxDelayedTimerEvent( void* context ) static void OnRxWindow1TimerEvent( void* context ) { MacCtx.RxWindow1Config.Channel = MacCtx.Channel; - MacCtx.RxWindow1Config.DrOffset = MacCtx.NvmCtx->MacParams.Rx1DrOffset; - MacCtx.RxWindow1Config.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; - MacCtx.RxWindow1Config.RepeaterSupport = MacCtx.NvmCtx->RepeaterSupport; + MacCtx.RxWindow1Config.DrOffset = Nvm.MacGroup2.MacParams.Rx1DrOffset; + MacCtx.RxWindow1Config.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; + MacCtx.RxWindow1Config.RepeaterSupport = Nvm.MacGroup2.MacParams.RepeaterSupport; /* ST_WORKAROUND: Keep repeater feature */ MacCtx.RxWindow1Config.RxContinuous = false; MacCtx.RxWindow1Config.RxSlot = RX_SLOT_WIN_1; @@ -1726,9 +1716,9 @@ static void OnRxWindow2TimerEvent( void* context ) return; } MacCtx.RxWindow2Config.Channel = MacCtx.Channel; - MacCtx.RxWindow2Config.Frequency = MacCtx.NvmCtx->MacParams.Rx2Channel.Frequency; - MacCtx.RxWindow2Config.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; - MacCtx.RxWindow2Config.RepeaterSupport = MacCtx.NvmCtx->RepeaterSupport; + MacCtx.RxWindow2Config.Frequency = Nvm.MacGroup2.MacParams.Rx2Channel.Frequency; + MacCtx.RxWindow2Config.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; + MacCtx.RxWindow2Config.RepeaterSupport = Nvm.MacGroup2.MacParams.RepeaterSupport; /* ST_WORKAROUND: Keep repeater feature */ MacCtx.RxWindow2Config.RxContinuous = false; MacCtx.RxWindow2Config.RxSlot = RX_SLOT_WIN_2; @@ -1743,7 +1733,7 @@ static void OnAckTimeoutTimerEvent( void* context ) { MacCtx.AckTimeoutRetry = true; } - if( MacCtx.NvmCtx->DeviceClass == CLASS_C ) + if( Nvm.MacGroup2.DeviceClass == CLASS_C ) { MacCtx.MacFlags.Bits.MacDone = 1; } @@ -1782,20 +1772,28 @@ static LoRaMacCryptoStatus_t GetFCntDown( AddressIdentifier_t addrID, FType_t fT *fCntID = FCNT_DOWN; } break; + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ +#if ( LORAMAC_MAX_MC_CTX > 0 ) case MULTICAST_0_ADDR: *fCntID = MC_FCNT_DOWN_0; break; +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) case MULTICAST_1_ADDR: *fCntID = MC_FCNT_DOWN_1; break; +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) case MULTICAST_2_ADDR: *fCntID = MC_FCNT_DOWN_2; break; +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) case MULTICAST_3_ADDR: *fCntID = MC_FCNT_DOWN_3; break; -#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 3 */ + /* ST_WORKAROUND_END */ default: return LORAMAC_CRYPTO_FAIL_FCNT_ID; } @@ -1807,42 +1805,43 @@ static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass ) { LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; - switch( MacCtx.NvmCtx->DeviceClass ) + switch( Nvm.MacGroup2.DeviceClass ) { case CLASS_A: { if( deviceClass == CLASS_A ) { // Revert back RxC parameters - MacCtx.NvmCtx->MacParams.RxCChannel = MacCtx.NvmCtx->MacParams.Rx2Channel; + Nvm.MacGroup2.MacParams.RxCChannel = Nvm.MacGroup2.MacParams.Rx2Channel; } if( deviceClass == CLASS_B ) { status = LoRaMacClassBSwitchClass( deviceClass ); if( status == LORAMAC_STATUS_OK ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; } } if( deviceClass == CLASS_C ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; MacCtx.RxWindowCConfig = MacCtx.RxWindow2Config; MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; for( int8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - if( MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.IsEnabled == true ) + if( Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.IsEnabled == true ) + // TODO: Check multicast channel device class. { - MacCtx.NvmCtx->MacParams.RxCChannel.Frequency = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.RxParams.ClassC.Frequency; - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.RxParams.ClassC.Datarate; + Nvm.MacGroup2.MacParams.RxCChannel.Frequency = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.RxParams.ClassC.Frequency; + Nvm.MacGroup2.MacParams.RxCChannel.Datarate = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.RxParams.ClassC.Datarate; MacCtx.RxWindowCConfig.Channel = MacCtx.Channel; - MacCtx.RxWindowCConfig.Frequency = MacCtx.NvmCtx->MacParams.RxCChannel.Frequency; - MacCtx.RxWindowCConfig.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; - MacCtx.RxWindowCConfig.RepeaterSupport = MacCtx.NvmCtx->RepeaterSupport; + MacCtx.RxWindowCConfig.Frequency = Nvm.MacGroup2.MacParams.RxCChannel.Frequency; + MacCtx.RxWindowCConfig.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; + MacCtx.RxWindowCConfig.RepeaterSupport = Nvm.MacGroup2.MacParams.RepeaterSupport; /* ST_WORKAROUND: Keep repeater feature */ MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C_MULTICAST; MacCtx.RxWindowCConfig.RxContinuous = true; break; @@ -1865,7 +1864,7 @@ static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass ) status = LoRaMacClassBSwitchClass( deviceClass ); if( status == LORAMAC_STATUS_OK ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; } break; } @@ -1873,7 +1872,7 @@ static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass ) { if( deviceClass == CLASS_A ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; // Set the radio into sleep to setup a defined state Radio.Sleep( ); @@ -1893,17 +1892,17 @@ static uint8_t GetMaxAppPayloadWithoutFOptsLength( int8_t datarate ) PhyParam_t phyParam; // Setup PHY request - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; getPhy.Datarate = datarate; getPhy.Attribute = PHY_MAX_PAYLOAD; - + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ // Get the maximum payload length - if( MacCtx.NvmCtx->RepeaterSupport == true ) + if( Nvm.MacGroup2.MacParams.RepeaterSupport == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } - - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + /* ST_WORKAROUND_END */ + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); return phyParam.Value; } @@ -1973,22 +1972,22 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm // Fill parameter structure linkAdrReq.Payload = &payload[macIndex - 1]; linkAdrReq.PayloadSize = commandsSize - ( macIndex - 1 ); - linkAdrReq.AdrEnabled = MacCtx.NvmCtx->AdrCtrlOn; - linkAdrReq.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - linkAdrReq.CurrentDatarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - linkAdrReq.CurrentTxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - linkAdrReq.CurrentNbRep = MacCtx.NvmCtx->MacParams.ChannelsNbTrans; - linkAdrReq.Version = MacCtx.NvmCtx->Version; + linkAdrReq.AdrEnabled = Nvm.MacGroup2.AdrCtrlOn; + linkAdrReq.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + linkAdrReq.CurrentDatarate = Nvm.MacGroup1.ChannelsDatarate; + linkAdrReq.CurrentTxPower = Nvm.MacGroup1.ChannelsTxPower; + linkAdrReq.CurrentNbRep = Nvm.MacGroup2.MacParams.ChannelsNbTrans; + linkAdrReq.Version = Nvm.MacGroup2.Version; // Process the ADR requests - status = RegionLinkAdrReq( MacCtx.NvmCtx->Region, &linkAdrReq, &linkAdrDatarate, + status = RegionLinkAdrReq( Nvm.MacGroup2.Region, &linkAdrReq, &linkAdrDatarate, &linkAdrTxPower, &linkAdrNbRep, &linkAdrNbBytesParsed ); if( ( status & 0x07 ) == 0x07 ) { - MacCtx.NvmCtx->MacParams.ChannelsDatarate = linkAdrDatarate; - MacCtx.NvmCtx->MacParams.ChannelsTxPower = linkAdrTxPower; - MacCtx.NvmCtx->MacParams.ChannelsNbTrans = linkAdrNbRep; + Nvm.MacGroup1.ChannelsDatarate = linkAdrDatarate; + Nvm.MacGroup1.ChannelsTxPower = linkAdrTxPower; + Nvm.MacGroup2.MacParams.ChannelsNbTrans = linkAdrNbRep; } // Add the answers to the buffer @@ -2003,8 +2002,8 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm } case SRV_MAC_DUTY_CYCLE_REQ: { - MacCtx.NvmCtx->MaxDCycle = payload[macIndex++] & 0x0F; - MacCtx.NvmCtx->AggregatedDCycle = 1 << MacCtx.NvmCtx->MaxDCycle; + Nvm.MacGroup2.MaxDCycle = payload[macIndex++] & 0x0F; + Nvm.MacGroup2.AggregatedDCycle = 1 << Nvm.MacGroup2.MaxDCycle; LoRaMacCommandsAddCmd( MOTE_MAC_DUTY_CYCLE_ANS, macCmdPayload, 0 ); break; } @@ -2023,15 +2022,15 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm rxParamSetupReq.Frequency *= 100; // Perform request on region - status = RegionRxParamSetupReq( MacCtx.NvmCtx->Region, &rxParamSetupReq ); + status = RegionRxParamSetupReq( Nvm.MacGroup2.Region, &rxParamSetupReq ); if( ( status & 0x07 ) == 0x07 ) { - MacCtx.NvmCtx->MacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate; - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate = rxParamSetupReq.Datarate; - MacCtx.NvmCtx->MacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency; - MacCtx.NvmCtx->MacParams.RxCChannel.Frequency = rxParamSetupReq.Frequency; - MacCtx.NvmCtx->MacParams.Rx1DrOffset = rxParamSetupReq.DrOffset; + Nvm.MacGroup2.MacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate; + Nvm.MacGroup2.MacParams.RxCChannel.Datarate = rxParamSetupReq.Datarate; + Nvm.MacGroup2.MacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency; + Nvm.MacGroup2.MacParams.RxCChannel.Frequency = rxParamSetupReq.Frequency; + Nvm.MacGroup2.MacParams.Rx1DrOffset = rxParamSetupReq.DrOffset; } macCmdPayload[0] = status; LoRaMacCommandsAddCmd( MOTE_MAC_RX_PARAM_SETUP_ANS, macCmdPayload, 1 ); @@ -2067,10 +2066,13 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm chParam.Rx1Frequency = 0; chParam.DrRange.Value = payload[macIndex++]; - status = RegionNewChannelReq( MacCtx.NvmCtx->Region, &newChannelReq ); + status = ( uint8_t )RegionNewChannelReq( Nvm.MacGroup2.Region, &newChannelReq ); - macCmdPayload[0] = status; - LoRaMacCommandsAddCmd( MOTE_MAC_NEW_CHANNEL_ANS, macCmdPayload, 1 ); + if( ( int8_t )status >= 0 ) + { + macCmdPayload[0] = status; + LoRaMacCommandsAddCmd( MOTE_MAC_NEW_CHANNEL_ANS, macCmdPayload, 1 ); + } break; } case SRV_MAC_RX_TIMING_SETUP_REQ: @@ -2081,8 +2083,8 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm { delay++; } - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = delay * 1000; - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = MacCtx.NvmCtx->MacParams.ReceiveDelay1 + 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = delay * 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = Nvm.MacGroup2.MacParams.ReceiveDelay1 + 1000; LoRaMacCommandsAddCmd( MOTE_MAC_RX_TIMING_SETUP_ANS, macCmdPayload, 0 ); // Setup indication to inform the application SetMlmeScheduleUplinkIndication( ); @@ -2109,17 +2111,17 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm txParamSetupReq.MaxEirp = eirpDwellTime & 0x0F; // Check the status for correctness - if( RegionTxParamSetupReq( MacCtx.NvmCtx->Region, &txParamSetupReq ) != -1 ) + if( RegionTxParamSetupReq( Nvm.MacGroup2.Region, &txParamSetupReq ) != -1 ) { // Accept command - MacCtx.NvmCtx->MacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime; - MacCtx.NvmCtx->MacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime; - MacCtx.NvmCtx->MacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; + Nvm.MacGroup2.MacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime; + Nvm.MacGroup2.MacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime; + Nvm.MacGroup2.MacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; // Update the datarate in case of the new configuration limits it getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParams.ChannelsDatarate = MAX( MacCtx.NvmCtx->MacParams.ChannelsDatarate, ( int8_t )phyParam.Value ); + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup1.ChannelsDatarate = MAX( Nvm.MacGroup1.ChannelsDatarate, ( int8_t )phyParam.Value ); // Add command response LoRaMacCommandsAddCmd( MOTE_MAC_TX_PARAM_SETUP_ANS, macCmdPayload, 0 ); @@ -2137,11 +2139,15 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm dlChannelReq.Rx1Frequency |= ( uint32_t ) payload[macIndex++] << 16; dlChannelReq.Rx1Frequency *= 100; - status = RegionDlChannelReq( MacCtx.NvmCtx->Region, &dlChannelReq ); - macCmdPayload[0] = status; - LoRaMacCommandsAddCmd( MOTE_MAC_DL_CHANNEL_ANS, macCmdPayload, 1 ); - // Setup indication to inform the application - SetMlmeScheduleUplinkIndication( ); + status = ( uint8_t )RegionDlChannelReq( Nvm.MacGroup2.Region, &dlChannelReq ); + + if( ( int8_t )status >= 0 ) + { + macCmdPayload[0] = status; + LoRaMacCommandsAddCmd( MOTE_MAC_DL_CHANNEL_ANS, macCmdPayload, 1 ); + // Setup indication to inform the application + SetMlmeScheduleUplinkIndication( ); + } break; } case SRV_MAC_DEVICE_TIME_ANS: @@ -2253,31 +2259,32 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm } } +/* ST_WORKAROUND: Update Send request with new input parameter to allow delayed tx */ static LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuffer, uint16_t fBufferSize, bool allowDelayedTx ) { LoRaMacFrameCtrl_t fCtrl; LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; - int8_t datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - int8_t txPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - uint32_t adrAckCounter = MacCtx.NvmCtx->AdrAckCounter; + int8_t datarate = Nvm.MacGroup1.ChannelsDatarate; + int8_t txPower = Nvm.MacGroup1.ChannelsTxPower; + uint32_t adrAckCounter = Nvm.MacGroup1.AdrAckCounter; CalcNextAdrParams_t adrNext; // Check if we are joined - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { return LORAMAC_STATUS_NO_NETWORK_JOINED; } - if( MacCtx.NvmCtx->MaxDCycle == 0 ) + if( Nvm.MacGroup2.MaxDCycle == 0 ) { - MacCtx.NvmCtx->AggregatedTimeOff = 0; + Nvm.MacGroup1.AggregatedTimeOff = 0; } fCtrl.Value = 0; fCtrl.Bits.FOptsLen = 0; - fCtrl.Bits.Adr = MacCtx.NvmCtx->AdrCtrlOn; + fCtrl.Bits.Adr = Nvm.MacGroup2.AdrCtrlOn; // Check class b - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { fCtrl.Bits.FPending = 1; } @@ -2287,25 +2294,25 @@ static LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuff } // Check server ack - if( MacCtx.NvmCtx->SrvAckRequested == true ) + if( Nvm.MacGroup1.SrvAckRequested == true ) { fCtrl.Bits.Ack = 1; } // ADR next request - adrNext.Version = MacCtx.NvmCtx->Version; + adrNext.Version = Nvm.MacGroup2.Version; adrNext.UpdateChanMask = true; adrNext.AdrEnabled = fCtrl.Bits.Adr; - adrNext.AdrAckCounter = MacCtx.NvmCtx->AdrAckCounter; + adrNext.AdrAckCounter = Nvm.MacGroup1.AdrAckCounter; adrNext.AdrAckLimit = MacCtx.AdrAckLimit; adrNext.AdrAckDelay = MacCtx.AdrAckDelay; - adrNext.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - adrNext.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - adrNext.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - adrNext.Region = MacCtx.NvmCtx->Region; + adrNext.Datarate = Nvm.MacGroup1.ChannelsDatarate; + adrNext.TxPower = Nvm.MacGroup1.ChannelsTxPower; + adrNext.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + adrNext.Region = Nvm.MacGroup2.Region; - fCtrl.Bits.AdrAckReq = LoRaMacAdrCalcNext( &adrNext, &MacCtx.NvmCtx->MacParams.ChannelsDatarate, - &MacCtx.NvmCtx->MacParams.ChannelsTxPower, &adrAckCounter ); + fCtrl.Bits.AdrAckReq = LoRaMacAdrCalcNext( &adrNext, &Nvm.MacGroup1.ChannelsDatarate, + &Nvm.MacGroup1.ChannelsTxPower, &adrAckCounter ); // Prepare the frame status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); @@ -2314,7 +2321,7 @@ static LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuff if( ( status == LORAMAC_STATUS_OK ) || ( status == LORAMAC_STATUS_SKIPPED_APP_DATA ) ) { // Schedule frame, do not allow delayed transmissions - status = ScheduleTx( allowDelayedTx ); + status = ScheduleTx( allowDelayedTx ); /* ST_WORKAROUND: Update Send request with new input parameter to allow delayed tx */ } // Post processing @@ -2322,14 +2329,14 @@ static LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuff { // Bad case - restore // Store local variables - MacCtx.NvmCtx->MacParams.ChannelsDatarate = datarate; - MacCtx.NvmCtx->MacParams.ChannelsTxPower = txPower; + Nvm.MacGroup1.ChannelsDatarate = datarate; + Nvm.MacGroup1.ChannelsTxPower = txPower; } else { // Good case - MacCtx.NvmCtx->SrvAckRequested = false; - MacCtx.NvmCtx->AdrAckCounter = adrAckCounter; + Nvm.MacGroup1.SrvAckRequested = false; + Nvm.MacGroup1.AdrAckCounter = adrAckCounter; // Remove all none sticky MAC commands if( LoRaMacCommandsRemoveNoneStickyCmds( ) != LORAMAC_COMMANDS_SUCCESS ) { @@ -2384,7 +2391,7 @@ static LoRaMacStatus_t CheckForClassBCollision( void ) return LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME; } - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { if( LoRaMacClassBIsPingExpected( ) == true ) { @@ -2401,29 +2408,29 @@ static LoRaMacStatus_t CheckForClassBCollision( void ) static void ComputeRxWindowParameters( void ) { // Compute Rx1 windows parameters - RegionComputeRxWindowParameters( MacCtx.NvmCtx->Region, - RegionApplyDrOffset( MacCtx.NvmCtx->Region, - MacCtx.NvmCtx->MacParams.DownlinkDwellTime, - MacCtx.NvmCtx->MacParams.ChannelsDatarate, - MacCtx.NvmCtx->MacParams.Rx1DrOffset ), - MacCtx.NvmCtx->MacParams.MinRxSymbols, - MacCtx.NvmCtx->MacParams.SystemMaxRxError, + RegionComputeRxWindowParameters( Nvm.MacGroup2.Region, + RegionApplyDrOffset( Nvm.MacGroup2.Region, + Nvm.MacGroup2.MacParams.DownlinkDwellTime, + Nvm.MacGroup1.ChannelsDatarate, + Nvm.MacGroup2.MacParams.Rx1DrOffset ), + Nvm.MacGroup2.MacParams.MinRxSymbols, + Nvm.MacGroup2.MacParams.SystemMaxRxError, &MacCtx.RxWindow1Config ); // Compute Rx2 windows parameters - RegionComputeRxWindowParameters( MacCtx.NvmCtx->Region, - MacCtx.NvmCtx->MacParams.Rx2Channel.Datarate, - MacCtx.NvmCtx->MacParams.MinRxSymbols, - MacCtx.NvmCtx->MacParams.SystemMaxRxError, + RegionComputeRxWindowParameters( Nvm.MacGroup2.Region, + Nvm.MacGroup2.MacParams.Rx2Channel.Datarate, + Nvm.MacGroup2.MacParams.MinRxSymbols, + Nvm.MacGroup2.MacParams.SystemMaxRxError, &MacCtx.RxWindow2Config ); // Default setup, in case the device joined - MacCtx.RxWindow1Delay = MacCtx.NvmCtx->MacParams.ReceiveDelay1 + MacCtx.RxWindow1Config.WindowOffset; - MacCtx.RxWindow2Delay = MacCtx.NvmCtx->MacParams.ReceiveDelay2 + MacCtx.RxWindow2Config.WindowOffset; + MacCtx.RxWindow1Delay = Nvm.MacGroup2.MacParams.ReceiveDelay1 + MacCtx.RxWindow1Config.WindowOffset; + MacCtx.RxWindow2Delay = Nvm.MacGroup2.MacParams.ReceiveDelay2 + MacCtx.RxWindow2Config.WindowOffset; - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { - MacCtx.RxWindow1Delay = MacCtx.NvmCtx->MacParams.JoinAcceptDelay1 + MacCtx.RxWindow1Config.WindowOffset; - MacCtx.RxWindow2Delay = MacCtx.NvmCtx->MacParams.JoinAcceptDelay2 + MacCtx.RxWindow2Config.WindowOffset; + MacCtx.RxWindow1Delay = Nvm.MacGroup2.MacParams.JoinAcceptDelay1 + MacCtx.RxWindow1Config.WindowOffset; + MacCtx.RxWindow2Delay = Nvm.MacGroup2.MacParams.JoinAcceptDelay2 + MacCtx.RxWindow2Config.WindowOffset; } } @@ -2431,14 +2438,14 @@ static LoRaMacStatus_t VerifyTxFrame( void ) { size_t macCmdsSize = 0; - if( MacCtx.NvmCtx->NetworkActivation != ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation != ACTIVATION_TYPE_NONE ) { if( LoRaMacCommandsGetSizeSerializedCmds( &macCmdsSize ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } - if( ValidatePayloadLength( MacCtx.AppDataSize, MacCtx.NvmCtx->MacParams.ChannelsDatarate, macCmdsSize ) == false ) + if( ValidatePayloadLength( MacCtx.AppDataSize, Nvm.MacGroup1.ChannelsDatarate, macCmdsSize ) == false ) { return LORAMAC_STATUS_LENGTH_ERROR; } @@ -2498,24 +2505,24 @@ static LoRaMacStatus_t ScheduleTx( bool allowDelayedTx ) return status; } - nextChan.AggrTimeOff = MacCtx.NvmCtx->AggregatedTimeOff; - nextChan.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - nextChan.DutyCycleEnabled = MacCtx.NvmCtx->DutyCycleOn; - nextChan.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), MacCtx.NvmCtx->InitializationTime ); - nextChan.LastAggrTx = MacCtx.NvmCtx->LastTxDoneTime; + nextChan.AggrTimeOff = Nvm.MacGroup1.AggregatedTimeOff; + nextChan.Datarate = Nvm.MacGroup1.ChannelsDatarate; + nextChan.DutyCycleEnabled = Nvm.MacGroup2.DutyCycleOn; + nextChan.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), Nvm.MacGroup2.InitializationTime ); + nextChan.LastAggrTx = Nvm.MacGroup1.LastTxDoneTime; nextChan.LastTxIsJoinRequest = false; nextChan.Joined = true; nextChan.PktLen = MacCtx.PktBufferLen; // Setup the parameters based on the join status - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { nextChan.LastTxIsJoinRequest = true; nextChan.Joined = false; } // Select channel - status = RegionNextChannel( MacCtx.NvmCtx->Region, &nextChan, &MacCtx.Channel, &MacCtx.DutyCycleWaitTime, &MacCtx.NvmCtx->AggregatedTimeOff ); + status = RegionNextChannel( Nvm.MacGroup2.Region, &nextChan, &MacCtx.Channel, &MacCtx.DutyCycleWaitTime, &Nvm.MacGroup1.AggregatedTimeOff ); if( status != LORAMAC_STATUS_OK ) { @@ -2598,11 +2605,11 @@ static void CalculateBackOff( void ) { // Make sure that the calculation of the backoff time for the aggregated time off will only be done in // case the value is zero. It will be set to zero in the function RegionNextChannel. - if( MacCtx.NvmCtx->AggregatedTimeOff == 0 ) + if( Nvm.MacGroup1.AggregatedTimeOff == 0 ) { // Update aggregated time-off. This must be an assignment and no incremental // update as we do only calculate the time-off based on the last transmission - MacCtx.NvmCtx->AggregatedTimeOff = ( MacCtx.TxTimeOnAir * MacCtx.NvmCtx->AggregatedDCycle - MacCtx.TxTimeOnAir ); + Nvm.MacGroup1.AggregatedTimeOff = ( MacCtx.TxTimeOnAir * Nvm.MacGroup2.AggregatedDCycle - MacCtx.TxTimeOnAir ); } } @@ -2626,48 +2633,53 @@ static void RemoveMacCommands( LoRaMacRxSlot_t rxSlot, LoRaMacFrameCtrl_t fCtrl, } } + static void ResetMacParameters( void ) { - MacCtx.NvmCtx->NetworkActivation = ACTIVATION_TYPE_NONE; + LoRaMacClassBCallback_t classBCallbacks; + LoRaMacClassBParams_t classBParams; + + Nvm.MacGroup2.NetworkActivation = ACTIVATION_TYPE_NONE; // ADR counter - MacCtx.NvmCtx->AdrAckCounter = 0; + Nvm.MacGroup1.AdrAckCounter = 0; MacCtx.ChannelsNbTransCounter = 0; MacCtx.AckTimeoutRetries = 1; MacCtx.AckTimeoutRetriesCounter = 1; MacCtx.AckTimeoutRetry = false; - MacCtx.NvmCtx->MaxDCycle = 0; - MacCtx.NvmCtx->AggregatedDCycle = 1; + Nvm.MacGroup2.MaxDCycle = 0; + Nvm.MacGroup2.AggregatedDCycle = 1; - MacCtx.NvmCtx->MacParams.ChannelsTxPower = MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower; - MacCtx.NvmCtx->MacParams.ChannelsDatarate = MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate; - MacCtx.NvmCtx->MacParams.Rx1DrOffset = MacCtx.NvmCtx->MacParamsDefaults.Rx1DrOffset; - MacCtx.NvmCtx->MacParams.Rx2Channel = MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel; - MacCtx.NvmCtx->MacParams.RxCChannel = MacCtx.NvmCtx->MacParamsDefaults.RxCChannel; - MacCtx.NvmCtx->MacParams.UplinkDwellTime = MacCtx.NvmCtx->MacParamsDefaults.UplinkDwellTime; - MacCtx.NvmCtx->MacParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParamsDefaults.DownlinkDwellTime; - MacCtx.NvmCtx->MacParams.MaxEirp = MacCtx.NvmCtx->MacParamsDefaults.MaxEirp; - MacCtx.NvmCtx->MacParams.AntennaGain = MacCtx.NvmCtx->MacParamsDefaults.AntennaGain; + Nvm.MacGroup1.ChannelsTxPower = Nvm.MacGroup2.ChannelsTxPowerDefault; + Nvm.MacGroup1.ChannelsDatarate = Nvm.MacGroup2.ChannelsDatarateDefault; + Nvm.MacGroup2.MacParams.Rx1DrOffset = Nvm.MacGroup2.MacParamsDefaults.Rx1DrOffset; + Nvm.MacGroup2.MacParams.Rx2Channel = Nvm.MacGroup2.MacParamsDefaults.Rx2Channel; + Nvm.MacGroup2.MacParams.RxCChannel = Nvm.MacGroup2.MacParamsDefaults.RxCChannel; + Nvm.MacGroup2.MacParams.UplinkDwellTime = Nvm.MacGroup2.MacParamsDefaults.UplinkDwellTime; + Nvm.MacGroup2.MacParams.DownlinkDwellTime = Nvm.MacGroup2.MacParamsDefaults.DownlinkDwellTime; + Nvm.MacGroup2.MacParams.MaxEirp = Nvm.MacGroup2.MacParamsDefaults.MaxEirp; + Nvm.MacGroup2.MacParams.AntennaGain = Nvm.MacGroup2.MacParamsDefaults.AntennaGain; MacCtx.NodeAckRequested = false; - MacCtx.NvmCtx->SrvAckRequested = false; + Nvm.MacGroup1.SrvAckRequested = false; // Reset to application defaults InitDefaultsParams_t params; params.Type = INIT_TYPE_RESET_TO_DEFAULT_CHANNELS; - params.NvmCtx = NULL; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); + params.NvmGroup1 = &Nvm.RegionGroup1; + params.NvmGroup2 = &Nvm.RegionGroup2; + RegionInitDefaults( Nvm.MacGroup2.Region, ¶ms ); // Initialize channel index. MacCtx.Channel = 0; // Initialize Rx2 config parameters. MacCtx.RxWindow2Config.Channel = MacCtx.Channel; - MacCtx.RxWindow2Config.Frequency = MacCtx.NvmCtx->MacParams.Rx2Channel.Frequency; - MacCtx.RxWindow2Config.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; - MacCtx.RxWindow2Config.RepeaterSupport = MacCtx.NvmCtx->RepeaterSupport; + MacCtx.RxWindow2Config.Frequency = Nvm.MacGroup2.MacParams.Rx2Channel.Frequency; + MacCtx.RxWindow2Config.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; + MacCtx.RxWindow2Config.RepeaterSupport = Nvm.MacGroup2.MacParams.RepeaterSupport; /* ST_WORKAROUND: Keep repeater feature */ MacCtx.RxWindow2Config.RxContinuous = false; MacCtx.RxWindow2Config.RxSlot = RX_SLOT_WIN_2; @@ -2676,6 +2688,28 @@ static void ResetMacParameters( void ) MacCtx.RxWindowCConfig.RxContinuous = true; MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; + // Initialize class b + // Apply callback + classBCallbacks.GetTemperatureLevel = NULL; + classBCallbacks.MacProcessNotify = NULL; + + if( MacCtx.MacCallbacks != NULL ) + { + classBCallbacks.GetTemperatureLevel = MacCtx.MacCallbacks->GetTemperatureLevel; + classBCallbacks.MacProcessNotify = MacCtx.MacCallbacks->MacProcessNotify; + } + + // Must all be static. Don't use local references. + classBParams.MlmeIndication = &MacCtx.MlmeIndication; + classBParams.McpsIndication = &MacCtx.McpsIndication; + classBParams.MlmeConfirm = &MacCtx.MlmeConfirm; + classBParams.LoRaMacFlags = &MacCtx.MacFlags; + classBParams.LoRaMacDevAddr = &Nvm.MacGroup2.DevAddr; + classBParams.LoRaMacRegion = &Nvm.MacGroup2.Region; + classBParams.LoRaMacParams = &Nvm.MacGroup2.MacParams; + classBParams.MulticastChannels = &Nvm.MacGroup2.MulticastChannelList[0]; + + LoRaMacClassBInit( &classBParams, &classBCallbacks, &Nvm.ClassB ); } /*! @@ -2691,9 +2725,9 @@ static void RxWindowSetup( TimerEvent_t* rxTimer, RxConfigParams_t* rxConfig ) // Ensure the radio is Idle Radio.Standby( ); - if( RegionRxConfig( MacCtx.NvmCtx->Region, rxConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) + if( RegionRxConfig( Nvm.MacGroup2.Region, rxConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) { - Radio.Rx( MacCtx.NvmCtx->MacParams.MaxRxWindow ); + Radio.Rx( Nvm.MacGroup2.MacParams.MaxRxWindow ); MacCtx.RxSlot = rxConfig->RxSlot; } } @@ -2701,10 +2735,10 @@ static void RxWindowSetup( TimerEvent_t* rxTimer, RxConfigParams_t* rxConfig ) static void OpenContinuousRxCWindow( void ) { // Compute RxC windows parameters - RegionComputeRxWindowParameters( MacCtx.NvmCtx->Region, - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate, - MacCtx.NvmCtx->MacParams.MinRxSymbols, - MacCtx.NvmCtx->MacParams.SystemMaxRxError, + RegionComputeRxWindowParameters( Nvm.MacGroup2.Region, + Nvm.MacGroup2.MacParams.RxCChannel.Datarate, + Nvm.MacGroup2.MacParams.MinRxSymbols, + Nvm.MacGroup2.MacParams.SystemMaxRxError, &MacCtx.RxWindowCConfig ); MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; @@ -2713,7 +2747,7 @@ static void OpenContinuousRxCWindow( void ) // At this point the Radio should be idle. // Thus, there is no need to set the radio in standby mode. - if( RegionRxConfig( MacCtx.NvmCtx->Region, &MacCtx.RxWindowCConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) + if( RegionRxConfig( Nvm.MacGroup2.Region, &MacCtx.RxWindowCConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) { Radio.Rx( 0 ); // Continuous mode MacCtx.RxSlot = MacCtx.RxWindowCConfig.RxSlot; @@ -2748,7 +2782,7 @@ static LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t MacCtx.TxMsg.Message.Data.BufSize = LORAMAC_PHY_MAXPAYLOAD; MacCtx.TxMsg.Message.Data.MHDR.Value = macHdr->Value; MacCtx.TxMsg.Message.Data.FPort = fPort; - MacCtx.TxMsg.Message.Data.FHDR.DevAddr = MacCtx.NvmCtx->DevAddr; + MacCtx.TxMsg.Message.Data.FHDR.DevAddr = Nvm.MacGroup2.DevAddr; MacCtx.TxMsg.Message.Data.FHDR.FCtrl.Value = fCtrl->Value; MacCtx.TxMsg.Message.Data.FRMPayloadSize = MacCtx.AppDataSize; MacCtx.TxMsg.Message.Data.FRMPayload = MacCtx.AppData; @@ -2772,7 +2806,7 @@ static LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t if( macCmdsSize > 0 ) { - availableSize = GetMaxAppPayloadWithoutFOptsLength( MacCtx.NvmCtx->MacParams.ChannelsDatarate ); + availableSize = GetMaxAppPayloadWithoutFOptsLength( Nvm.MacGroup1.ChannelsDatarate ); // There is application payload available and the MAC commands fit into FOpts field. if( ( MacCtx.AppDataSize > 0 ) && ( macCmdsSize <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) ) @@ -2789,7 +2823,7 @@ static LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t else if( ( MacCtx.AppDataSize > 0 ) && ( macCmdsSize > LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) ) { - if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.NvmCtx->MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) + if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } @@ -2798,14 +2832,14 @@ static LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t // No application payload available therefore add all mac commands to the FRMPayload. else { - if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.NvmCtx->MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) + if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } // Force FPort to be zero MacCtx.TxMsg.Message.Data.FPort = 0; - MacCtx.TxMsg.Message.Data.FRMPayload = MacCtx.NvmCtx->MacCommandsBuffer; + MacCtx.TxMsg.Message.Data.FRMPayload = MacCtx.MacCommandsBuffer; MacCtx.TxMsg.Message.Data.FRMPayloadSize = macCmdsSize; } } @@ -2832,16 +2866,16 @@ static LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) int8_t txPower = 0; txConfig.Channel = channel; - txConfig.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - txConfig.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - txConfig.MaxEirp = MacCtx.NvmCtx->MacParams.MaxEirp; - txConfig.AntennaGain = MacCtx.NvmCtx->MacParams.AntennaGain; + txConfig.Datarate = Nvm.MacGroup1.ChannelsDatarate; + txConfig.TxPower = Nvm.MacGroup1.ChannelsTxPower; + txConfig.MaxEirp = Nvm.MacGroup2.MacParams.MaxEirp; + txConfig.AntennaGain = Nvm.MacGroup2.MacParams.AntennaGain; txConfig.PktLen = MacCtx.PktBufferLen; - RegionTxConfig( MacCtx.NvmCtx->Region, &txConfig, &txPower, &MacCtx.TxTimeOnAir ); + RegionTxConfig( Nvm.MacGroup2.Region, &txConfig, &txPower, &MacCtx.TxTimeOnAir ); MacCtx.McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - MacCtx.McpsConfirm.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; + MacCtx.McpsConfirm.Datarate = Nvm.MacGroup1.ChannelsDatarate; MacCtx.McpsConfirm.TxPower = txPower; MacCtx.McpsConfirm.Channel = channel; @@ -2861,7 +2895,7 @@ static LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) } } - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { // Stop slots for class b LoRaMacClassBStopRxSlots( ); @@ -2870,7 +2904,7 @@ static LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) LoRaMacClassBHaltBeaconing( ); // Secure frame - status = SecureFrame( MacCtx.NvmCtx->MacParams.ChannelsDatarate, MacCtx.Channel ); + status = SecureFrame( Nvm.MacGroup1.ChannelsDatarate, MacCtx.Channel ); if( status != LORAMAC_STATUS_OK ) { return status; @@ -2893,13 +2927,13 @@ static LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ) ContinuousWaveParams_t continuousWave; continuousWave.Channel = MacCtx.Channel; - continuousWave.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - continuousWave.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - continuousWave.MaxEirp = MacCtx.NvmCtx->MacParams.MaxEirp; - continuousWave.AntennaGain = MacCtx.NvmCtx->MacParams.AntennaGain; + continuousWave.Datarate = Nvm.MacGroup1.ChannelsDatarate; + continuousWave.TxPower = Nvm.MacGroup1.ChannelsTxPower; + continuousWave.MaxEirp = Nvm.MacGroup2.MacParams.MaxEirp; + continuousWave.AntennaGain = Nvm.MacGroup2.MacParams.AntennaGain; continuousWave.Timeout = timeout; - RegionSetContinuousWave( MacCtx.NvmCtx->Region, &continuousWave ); + RegionSetContinuousWave( Nvm.MacGroup2.Region, &continuousWave ); MacCtx.MacState |= LORAMAC_TX_RUNNING; @@ -2915,24 +2949,17 @@ static LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequenc return LORAMAC_STATUS_OK; } -static LoRaMacCtxs_t* GetCtxs( void ) +LoRaMacNvmData_t* GetNvmData( void ) { - Contexts.MacNvmCtx = &NvmMacCtx; - Contexts.MacNvmCtxSize = sizeof( NvmMacCtx ); - Contexts.CryptoNvmCtx = LoRaMacCryptoGetNvmCtx( &Contexts.CryptoNvmCtxSize ); - GetNvmCtxParams_t params ={ 0 }; - Contexts.RegionNvmCtx = RegionGetNvmCtx( MacCtx.NvmCtx->Region, ¶ms ); - Contexts.RegionNvmCtxSize = params.nvmCtxSize; - Contexts.SecureElementNvmCtx = SecureElementGetNvmCtx( &Contexts.SecureElementNvmCtxSize ); - Contexts.CommandsNvmCtx = LoRaMacCommandsGetNvmCtx( &Contexts.CommandsNvmCtxSize ); - Contexts.ClassBNvmCtx = LoRaMacClassBGetNvmCtx( &Contexts.ClassBNvmCtxSize ); - Contexts.ConfirmQueueNvmCtx = LoRaMacConfirmQueueGetNvmCtx( &Contexts.ConfirmQueueNvmCtxSize ); - return &Contexts; + return &Nvm; } -static LoRaMacStatus_t RestoreCtxs( LoRaMacCtxs_t* contexts ) +LoRaMacStatus_t RestoreNvmData( LoRaMacNvmData_t* nvm ) { - if( contexts == NULL ) + uint32_t crc = 0; + + // Status and parameter validation + if( nvm == NULL ) { return LORAMAC_STATUS_PARAMETER_INVALID; } @@ -2941,47 +2968,64 @@ static LoRaMacStatus_t RestoreCtxs( LoRaMacCtxs_t* contexts ) return LORAMAC_STATUS_BUSY; } - if( contexts->MacNvmCtx != NULL ) + // Crypto + crc = Crc32( ( uint8_t* ) &nvm->Crypto, sizeof( nvm->Crypto ) - + sizeof( nvm->Crypto.Crc32 ) ); + if( crc == nvm->Crypto.Crc32 ) { - memcpy1( ( uint8_t* ) &NvmMacCtx, ( uint8_t* ) contexts->MacNvmCtx, contexts->MacNvmCtxSize ); + memcpy1( ( uint8_t* ) &Nvm.Crypto, ( uint8_t* ) &nvm->Crypto, + sizeof( Nvm.Crypto ) ); } - InitDefaultsParams_t params; - params.Type = INIT_TYPE_RESTORE_CTX; - params.NvmCtx = contexts->RegionNvmCtx; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); - - // Initialize RxC config parameters. - MacCtx.RxWindowCConfig.Channel = MacCtx.Channel; - MacCtx.RxWindowCConfig.Frequency = MacCtx.NvmCtx->MacParams.RxCChannel.Frequency; - MacCtx.RxWindowCConfig.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; - MacCtx.RxWindowCConfig.RepeaterSupport = MacCtx.NvmCtx->RepeaterSupport; - MacCtx.RxWindowCConfig.RxContinuous = true; - MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; - - if( SecureElementRestoreNvmCtx( contexts->SecureElementNvmCtx ) != SECURE_ELEMENT_SUCCESS ) + // MacGroup1 + crc = Crc32( ( uint8_t* ) &nvm->MacGroup1, sizeof( nvm->MacGroup1 ) - + sizeof( nvm->MacGroup1.Crc32 ) ); + if( crc == nvm->MacGroup1.Crc32 ) { - return LORAMAC_STATUS_CRYPTO_ERROR; + memcpy1( ( uint8_t* ) &Nvm.MacGroup1, ( uint8_t* ) &nvm->MacGroup1, + sizeof( Nvm.MacGroup1 ) ); } - if( LoRaMacCryptoRestoreNvmCtx( contexts->CryptoNvmCtx ) != LORAMAC_CRYPTO_SUCCESS ) + // MacGroup2 + crc = Crc32( ( uint8_t* ) &nvm->MacGroup2, sizeof( nvm->MacGroup2 ) - + sizeof( nvm->MacGroup2.Crc32 ) ); + if( crc == nvm->MacGroup2.Crc32 ) { - return LORAMAC_STATUS_CRYPTO_ERROR; + memcpy1( ( uint8_t* ) &Nvm.MacGroup2, ( uint8_t* ) &nvm->MacGroup2, + sizeof( Nvm.MacGroup2 ) ); + + // Initialize RxC config parameters. + MacCtx.RxWindowCConfig.Channel = MacCtx.Channel; + MacCtx.RxWindowCConfig.Frequency = Nvm.MacGroup2.MacParams.RxCChannel.Frequency; + MacCtx.RxWindowCConfig.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; + MacCtx.RxWindowCConfig.RxContinuous = true; + MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; } - if( LoRaMacCommandsRestoreNvmCtx( contexts->CommandsNvmCtx ) != LORAMAC_COMMANDS_SUCCESS ) + // Secure Element + crc = Crc32( ( uint8_t* ) &nvm->SecureElement, sizeof( nvm->SecureElement ) - + sizeof( nvm->SecureElement.Crc32 ) ); + if( crc == nvm->SecureElement.Crc32 ) { - return LORAMAC_STATUS_MAC_COMMAD_ERROR; + memcpy1( ( uint8_t* ) &Nvm.SecureElement,( uint8_t* ) &nvm->SecureElement, + sizeof( Nvm.SecureElement ) ); } - if( LoRaMacClassBRestoreNvmCtx( contexts->ClassBNvmCtx ) != true ) + // Region + crc = Crc32( ( uint8_t* ) &nvm->RegionGroup1, sizeof( nvm->RegionGroup1 ) - + sizeof( nvm->RegionGroup1.Crc32 ) ); + if( crc == nvm->RegionGroup1.Crc32 ) { - return LORAMAC_STATUS_CLASS_B_ERROR; + memcpy1( ( uint8_t* ) &Nvm.RegionGroup1,( uint8_t* ) &nvm->RegionGroup1, + sizeof( Nvm.RegionGroup1 ) ); } - if( LoRaMacConfirmQueueRestoreNvmCtx( contexts->ConfirmQueueNvmCtx ) != true ) + crc = Crc32( ( uint8_t* ) &nvm->ClassB, sizeof( nvm->ClassB ) - + sizeof( nvm->ClassB.Crc32 ) ); + if( crc == nvm->ClassB.Crc32 ) { - return LORAMAC_STATUS_CONFIRM_QUEUE_ERROR; + memcpy1( ( uint8_t* ) &Nvm.ClassB,( uint8_t* ) &nvm->ClassB, + sizeof( Nvm.ClassB ) ); } return LORAMAC_STATUS_OK; @@ -3043,20 +3087,20 @@ static bool CheckRetransUnconfirmedUplink( void ) { // Unconfirmed uplink, when all retransmissions are done. if( MacCtx.ChannelsNbTransCounter >= - MacCtx.NvmCtx->MacParams.ChannelsNbTrans ) + Nvm.MacGroup2.MacParams.ChannelsNbTrans ) { return true; } else if( MacCtx.MacFlags.Bits.McpsInd == 1 ) { // For Class A stop in each case - if( MacCtx.NvmCtx->DeviceClass == CLASS_A ) + if( Nvm.MacGroup2.DeviceClass == CLASS_A ) { return true; } else {// For Class B & C stop only if the frame was received in RX1 window - if( MacCtx.McpsIndication.RxSlot == RX_SLOT_WIN_1 ) + if( MacCtx.RxStatus.RxSlot == RX_SLOT_WIN_1 ) { return true; } @@ -3086,13 +3130,13 @@ static bool CheckRetransConfirmedUplink( void ) static bool StopRetransmission( void ) { if( ( MacCtx.MacFlags.Bits.McpsInd == 0 ) || - ( ( MacCtx.McpsIndication.RxSlot != RX_SLOT_WIN_1 ) && - ( MacCtx.McpsIndication.RxSlot != RX_SLOT_WIN_2 ) ) ) + ( ( MacCtx.RxStatus.RxSlot != RX_SLOT_WIN_1 ) && + ( MacCtx.RxStatus.RxSlot != RX_SLOT_WIN_2 ) ) ) { // Maximum repetitions without downlink. Increase ADR Ack counter. // Only process the case when the MAC did not receive a downlink. - if( MacCtx.NvmCtx->AdrCtrlOn == true ) + if( Nvm.MacGroup2.AdrCtrlOn == true ) { - MacCtx.NvmCtx->AdrAckCounter++; + Nvm.MacGroup1.AdrAckCounter++; } } @@ -3104,6 +3148,15 @@ static bool StopRetransmission( void ) return true; } +static void CallNvmDataChangeCallback( uint16_t notifyFlags ) +{ + if( ( MacCtx.MacCallbacks != NULL ) && + ( MacCtx.MacCallbacks->NvmDataChange != NULL ) ) + { + MacCtx.MacCallbacks->NvmDataChange ( notifyFlags ); + } +} + static void AckTimeoutRetriesProcess( void ) { if( MacCtx.AckTimeoutRetriesCounter < MacCtx.AckTimeoutRetries ) @@ -3115,10 +3168,10 @@ static void AckTimeoutRetriesProcess( void ) PhyParam_t phyParam; getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - getPhy.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParams.ChannelsDatarate = phyParam.Value; + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + getPhy.Datarate = Nvm.MacGroup1.ChannelsDatarate; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup1.ChannelsDatarate = phyParam.Value; } } } @@ -3129,8 +3182,9 @@ static void AckTimeoutRetriesFinalize( void ) { InitDefaultsParams_t params; params.Type = INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS; - params.NvmCtx = Contexts.RegionNvmCtx; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); + params.NvmGroup1 = &Nvm.RegionGroup1; + params.NvmGroup2 = &Nvm.RegionGroup2; + RegionInitDefaults( Nvm.MacGroup2.Region, ¶ms ); MacCtx.NodeAckRequested = false; MacCtx.McpsConfirm.AckReceived = false; @@ -3138,49 +3192,6 @@ static void AckTimeoutRetriesFinalize( void ) MacCtx.McpsConfirm.NbRetries = MacCtx.AckTimeoutRetriesCounter; } -static void CallNvmCtxCallback( LoRaMacNvmCtxModule_t module ) -{ - if( ( MacCtx.MacCallbacks != NULL ) && ( MacCtx.MacCallbacks->NvmContextChange != NULL ) ) - { - MacCtx.MacCallbacks->NvmContextChange( module ); - } -} - -static void EventMacNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_MAC ); -} - -static void EventRegionNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_REGION ); -} - -static void EventCryptoNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_CRYPTO ); -} - -static void EventSecureElementNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_SECURE_ELEMENT ); -} - -static void EventCommandsNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_COMMANDS ); -} - -static void EventClassBNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_CLASS_B ); -} - -static void EventConfirmQueueNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_CONFIRM_QUEUE ); -} - static uint8_t IsRequestPending( void ) { if( ( MacCtx.MacFlags.Bits.MlmeReq == 1 ) || @@ -3191,58 +3202,11 @@ static uint8_t IsRequestPending( void ) return 0; } -/* Exported functions ---------------------------------------------------------*/ -bool LoRaMacIsBusy( void ) -{ - if( ( MacCtx.MacState == LORAMAC_IDLE ) && - ( MacCtx.AllowRequests == LORAMAC_REQUEST_HANDLING_ON ) ) - { - return false; - } - return true; -} - -void LoRaMacProcess( void ) -{ - uint8_t noTx = 0x00; - - LoRaMacHandleIrqEvents( ); - LoRaMacClassBProcess( ); - - // MAC proceeded a state and is ready to check - if( MacCtx.MacFlags.Bits.MacDone == 1 ) - { - LoRaMacEnableRequests( LORAMAC_REQUEST_HANDLING_OFF ); - LoRaMacCheckForRxAbort( ); - - // An error occurs during transmitting - if( IsRequestPending( ) > 0 ) - { - noTx |= LoRaMacCheckForBeaconAcquisition( ); - } - - if( noTx == 0x00 ) - { - LoRaMacHandleMlmeRequest( ); - LoRaMacHandleMcpsRequest( ); - } - LoRaMacHandleRequestEvents( ); - LoRaMacHandleScheduleUplinkEvent( ); - LoRaMacEnableRequests( LORAMAC_REQUEST_HANDLING_ON ); - } - LoRaMacHandleIndicationEvents( ); - if( MacCtx.RxSlot == RX_SLOT_WIN_CLASS_C ) - { - OpenContinuousRxCWindow( ); - } -} LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacCallback_t* callbacks, LoRaMacRegion_t region ) { GetPhyParams_t getPhy; PhyParam_t phyParam; - LoRaMacClassBCallback_t classBCallbacks; - LoRaMacClassBParams_t classBParams; if( ( primitives == NULL ) || ( callbacks == NULL ) ) @@ -3264,125 +3228,125 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC } // Confirm queue reset - LoRaMacConfirmQueueInit( primitives, EventConfirmQueueNvmCtxChanged ); + LoRaMacConfirmQueueInit( primitives ); // Initialize the module context with zeros - memset1( ( uint8_t* ) &NvmMacCtx, 0x00, sizeof( LoRaMacNvmCtx_t ) ); + memset1( ( uint8_t* ) &Nvm, 0x00, sizeof( LoRaMacNvmData_t ) ); memset1( ( uint8_t* ) &MacCtx, 0x00, sizeof( LoRaMacCtx_t ) ); - MacCtx.NvmCtx = &NvmMacCtx; // Set non zero variables to its default value MacCtx.AckTimeoutRetriesCounter = 1; MacCtx.AckTimeoutRetries = 1; - MacCtx.NvmCtx->Region = region; - MacCtx.NvmCtx->DeviceClass = CLASS_A; - MacCtx.NvmCtx->RepeaterSupport = false; + Nvm.MacGroup2.Region = region; + Nvm.MacGroup2.DeviceClass = CLASS_A; + Nvm.MacGroup2.MacParams.RepeaterSupport = false; /* ST_WORKAROUND: Keep repeater feature */ // Setup version - MacCtx.NvmCtx->Version.Value = LORAMAC_VERSION; + Nvm.MacGroup2.Version.Value = LORAMAC_VERSION; // Reset to defaults getPhy.Attribute = PHY_DUTY_CYCLE; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->DutyCycleOn = ( bool ) phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.DutyCycleOn = ( bool ) phyParam.Value; getPhy.Attribute = PHY_DEF_TX_POWER; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.ChannelsTxPowerDefault = phyParam.Value; getPhy.Attribute = PHY_DEF_TX_DR; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.ChannelsDatarateDefault = phyParam.Value; getPhy.Attribute = PHY_MAX_RX_WINDOW; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.MaxRxWindow = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.MaxRxWindow = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY1; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay1 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay1 = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY2; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay2 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay2 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY1; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay1 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay1 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY2; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay2 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay2 = phyParam.Value; getPhy.Attribute = PHY_DEF_DR1_OFFSET; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.Rx1DrOffset = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.Rx1DrOffset = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel.Frequency = phyParam.Value; - MacCtx.NvmCtx->MacParamsDefaults.RxCChannel.Frequency = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.Rx2Channel.Frequency = phyParam.Value; + Nvm.MacGroup2.MacParamsDefaults.RxCChannel.Frequency = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_DR; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel.Datarate = phyParam.Value; - MacCtx.NvmCtx->MacParamsDefaults.RxCChannel.Datarate = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.Rx2Channel.Datarate = phyParam.Value; + Nvm.MacGroup2.MacParamsDefaults.RxCChannel.Datarate = phyParam.Value; getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.UplinkDwellTime = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.UplinkDwellTime = phyParam.Value; getPhy.Attribute = PHY_DEF_DOWNLINK_DWELL_TIME; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.DownlinkDwellTime = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.DownlinkDwellTime = phyParam.Value; getPhy.Attribute = PHY_DEF_MAX_EIRP; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.MaxEirp = phyParam.fValue; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.MaxEirp = phyParam.fValue; getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.AntennaGain = phyParam.fValue; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.AntennaGain = phyParam.fValue; getPhy.Attribute = PHY_DEF_ADR_ACK_LIMIT; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); MacCtx.AdrAckLimit = phyParam.Value; getPhy.Attribute = PHY_DEF_ADR_ACK_DELAY; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); MacCtx.AdrAckDelay = phyParam.Value; // Init parameters which are not set in function ResetMacParameters - MacCtx.NvmCtx->MacParamsDefaults.ChannelsNbTrans = 1; - MacCtx.NvmCtx->MacParamsDefaults.SystemMaxRxError = 10; - MacCtx.NvmCtx->MacParamsDefaults.MinRxSymbols = 6; - - MacCtx.NvmCtx->MacParams.SystemMaxRxError = MacCtx.NvmCtx->MacParamsDefaults.SystemMaxRxError; - MacCtx.NvmCtx->MacParams.MinRxSymbols = MacCtx.NvmCtx->MacParamsDefaults.MinRxSymbols; - MacCtx.NvmCtx->MacParams.MaxRxWindow = MacCtx.NvmCtx->MacParamsDefaults.MaxRxWindow; - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay1; - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay2; - MacCtx.NvmCtx->MacParams.JoinAcceptDelay1 = MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay1; - MacCtx.NvmCtx->MacParams.JoinAcceptDelay2 = MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay2; - MacCtx.NvmCtx->MacParams.ChannelsNbTrans = MacCtx.NvmCtx->MacParamsDefaults.ChannelsNbTrans; + Nvm.MacGroup2.MacParamsDefaults.ChannelsNbTrans = 1; + Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError = 10; + Nvm.MacGroup2.MacParamsDefaults.MinRxSymbols = 6; + + Nvm.MacGroup2.MacParams.SystemMaxRxError = Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError; + Nvm.MacGroup2.MacParams.MinRxSymbols = Nvm.MacGroup2.MacParamsDefaults.MinRxSymbols; + Nvm.MacGroup2.MacParams.MaxRxWindow = Nvm.MacGroup2.MacParamsDefaults.MaxRxWindow; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay1; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay2; + Nvm.MacGroup2.MacParams.JoinAcceptDelay1 = Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay1; + Nvm.MacGroup2.MacParams.JoinAcceptDelay2 = Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay2; + Nvm.MacGroup2.MacParams.ChannelsNbTrans = Nvm.MacGroup2.MacParamsDefaults.ChannelsNbTrans; InitDefaultsParams_t params; params.Type = INIT_TYPE_DEFAULTS; - params.NvmCtx = NULL; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); + params.NvmGroup1 = &Nvm.RegionGroup1; + params.NvmGroup2 = &Nvm.RegionGroup2; + RegionInitDefaults( Nvm.MacGroup2.Region, ¶ms ); + MacCtx.MacCallbacks = callbacks; ResetMacParameters( ); - MacCtx.NvmCtx->PublicNetwork = true; + Nvm.MacGroup2.PublicNetwork = true; MacCtx.MacPrimitives = primitives; - MacCtx.MacCallbacks = callbacks; MacCtx.MacFlags.Value = 0; MacCtx.MacState = LORAMAC_STOPPED; // Reset duty cycle times - MacCtx.NvmCtx->LastTxDoneTime = 0; - MacCtx.NvmCtx->AggregatedTimeOff = 0; + Nvm.MacGroup1.LastTxDoneTime = 0; + Nvm.MacGroup1.AggregatedTimeOff = 0; // Initialize timers TimerInit( &MacCtx.TxDelayedTimer, OnTxDelayedTimerEvent ); @@ -3391,7 +3355,7 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC TimerInit( &MacCtx.AckTimeoutTimer, OnAckTimeoutTimerEvent ); // Store the current initialization time - MacCtx.NvmCtx->InitializationTime = SysTimeGetMcuTime( ); + Nvm.MacGroup2.InitializationTime = SysTimeGetMcuTime( ); // Initialize Radio driver MacCtx.RadioEvents.TxDone = OnRadioTxDone; @@ -3402,25 +3366,25 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC Radio.Init( &MacCtx.RadioEvents ); // Initialize the Secure Element driver - if( SecureElementInit( EventSecureElementNvmCtxChanged ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementInit( &Nvm.SecureElement, callbacks->GetUniqueId ) != SECURE_ELEMENT_SUCCESS ) /* ST_WORKAROUND: Add unique ID callback as input parameter */ { return LORAMAC_STATUS_CRYPTO_ERROR; } // Initialize Crypto module - if( LoRaMacCryptoInit( EventCryptoNvmCtxChanged ) != LORAMAC_CRYPTO_SUCCESS ) + if( LoRaMacCryptoInit( &Nvm.Crypto ) != LORAMAC_CRYPTO_SUCCESS ) { return LORAMAC_STATUS_CRYPTO_ERROR; } // Initialize MAC commands module - if( LoRaMacCommandsInit( EventCommandsNvmCtxChanged ) != LORAMAC_COMMANDS_SUCCESS ) + if( LoRaMacCommandsInit( ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } // Set multicast downlink counter reference - if( LoRaMacCryptoSetMulticastReference( MacCtx.NvmCtx->MulticastChannelList ) != LORAMAC_CRYPTO_SUCCESS ) + if( LoRaMacCryptoSetMulticastReference( Nvm.MacGroup2.MulticastChannelList ) != LORAMAC_CRYPTO_SUCCESS ) { return LORAMAC_STATUS_CRYPTO_ERROR; } @@ -3428,31 +3392,9 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC // Random seed initialization srand1( Radio.Random( ) ); - Radio.SetPublicNetwork( MacCtx.NvmCtx->PublicNetwork ); + Radio.SetPublicNetwork( Nvm.MacGroup2.PublicNetwork ); Radio.Sleep( ); - // Initialize class b - // Apply callback - classBCallbacks.GetTemperatureLevel = NULL; - classBCallbacks.MacProcessNotify = NULL; - if( callbacks != NULL ) - { - classBCallbacks.GetTemperatureLevel = callbacks->GetTemperatureLevel; - classBCallbacks.MacProcessNotify = callbacks->MacProcessNotify; - } - - // Must all be static. Don't use local references. - classBParams.MlmeIndication = &MacCtx.MlmeIndication; - classBParams.McpsIndication = &MacCtx.McpsIndication; - classBParams.MlmeConfirm = &MacCtx.MlmeConfirm; - classBParams.LoRaMacFlags = &MacCtx.MacFlags; - classBParams.LoRaMacDevAddr = &MacCtx.NvmCtx->DevAddr; - classBParams.LoRaMacRegion = &MacCtx.NvmCtx->Region; - classBParams.LoRaMacParams = &MacCtx.NvmCtx->MacParams; - classBParams.MulticastChannels = &MacCtx.NvmCtx->MulticastChannelList[0]; - - LoRaMacClassBInit( &classBParams, &classBCallbacks, &EventClassBNvmCtxChanged ); - LoRaMacEnableRequests( LORAMAC_REQUEST_HANDLING_ON ); return LORAMAC_STATUS_OK; @@ -3481,9 +3423,9 @@ LoRaMacStatus_t LoRaMacStop( void ) LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) { CalcNextAdrParams_t adrNext; - uint32_t adrAckCounter = MacCtx.NvmCtx->AdrAckCounter; - int8_t datarate = MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate; - int8_t txPower = MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower; + uint32_t adrAckCounter = Nvm.MacGroup1.AdrAckCounter; + int8_t datarate = Nvm.MacGroup2.ChannelsDatarateDefault; + int8_t txPower = Nvm.MacGroup2.ChannelsTxPowerDefault; size_t macCmdsSize = 0; if( txInfo == NULL ) @@ -3492,16 +3434,16 @@ LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) } // Setup ADR request - adrNext.Version = MacCtx.NvmCtx->Version; + adrNext.Version = Nvm.MacGroup2.Version; adrNext.UpdateChanMask = false; - adrNext.AdrEnabled = MacCtx.NvmCtx->AdrCtrlOn; - adrNext.AdrAckCounter = MacCtx.NvmCtx->AdrAckCounter; + adrNext.AdrEnabled = Nvm.MacGroup2.AdrCtrlOn; + adrNext.AdrAckCounter = Nvm.MacGroup1.AdrAckCounter; adrNext.AdrAckLimit = MacCtx.AdrAckLimit; adrNext.AdrAckDelay = MacCtx.AdrAckDelay; - adrNext.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - adrNext.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - adrNext.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - adrNext.Region = MacCtx.NvmCtx->Region; + adrNext.Datarate = Nvm.MacGroup1.ChannelsDatarate; + adrNext.TxPower = Nvm.MacGroup1.ChannelsTxPower; + adrNext.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + adrNext.Region = Nvm.MacGroup2.Region; // We call the function for information purposes only. We don't want to // apply the datarate, the tx power and the ADR ack counter. @@ -3551,12 +3493,12 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t* mibGet ) { case MIB_DEVICE_CLASS: { - mibGet->Param.Class = MacCtx.NvmCtx->DeviceClass; + mibGet->Param.Class = Nvm.MacGroup2.DeviceClass; break; } case MIB_NETWORK_ACTIVATION: { - mibGet->Param.NetworkActivation = MacCtx.NvmCtx->NetworkActivation; + mibGet->Param.NetworkActivation = Nvm.MacGroup2.NetworkActivation; break; } case MIB_DEV_EUI: @@ -3571,61 +3513,63 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t* mibGet ) } case MIB_ADR: { - mibGet->Param.AdrEnable = MacCtx.NvmCtx->AdrCtrlOn; + mibGet->Param.AdrEnable = Nvm.MacGroup2.AdrCtrlOn; break; } case MIB_NET_ID: { - mibGet->Param.NetID = MacCtx.NvmCtx->NetID; + mibGet->Param.NetID = Nvm.MacGroup2.NetID; break; } case MIB_DEV_ADDR: { - mibGet->Param.DevAddr = MacCtx.NvmCtx->DevAddr; + mibGet->Param.DevAddr = Nvm.MacGroup2.DevAddr; break; } case MIB_PUBLIC_NETWORK: { - mibGet->Param.EnablePublicNetwork = MacCtx.NvmCtx->PublicNetwork; + mibGet->Param.EnablePublicNetwork = Nvm.MacGroup2.PublicNetwork; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case MIB_REPEATER_SUPPORT: { - mibGet->Param.EnableRepeaterSupport = MacCtx.NvmCtx->RepeaterSupport; + mibGet->Param.EnableRepeaterSupport = Nvm.MacGroup2.MacParams.RepeaterSupport; break; } + /* ST_WORKAROUND_END */ case MIB_CHANNELS: { getPhy.Attribute = PHY_CHANNELS; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); mibGet->Param.ChannelList = phyParam.Channels; break; } case MIB_RX2_CHANNEL: { - mibGet->Param.Rx2Channel = MacCtx.NvmCtx->MacParams.Rx2Channel; + mibGet->Param.Rx2Channel = Nvm.MacGroup2.MacParams.Rx2Channel; break; } case MIB_RX2_DEFAULT_CHANNEL: { - mibGet->Param.Rx2Channel = MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel; + mibGet->Param.Rx2Channel = Nvm.MacGroup2.MacParamsDefaults.Rx2Channel; break; } case MIB_RXC_CHANNEL: { - mibGet->Param.RxCChannel = MacCtx.NvmCtx->MacParams.RxCChannel; + mibGet->Param.RxCChannel = Nvm.MacGroup2.MacParams.RxCChannel; break; } case MIB_RXC_DEFAULT_CHANNEL: { - mibGet->Param.RxCChannel = MacCtx.NvmCtx->MacParamsDefaults.RxCChannel; + mibGet->Param.RxCChannel = Nvm.MacGroup2.MacParamsDefaults.RxCChannel; break; } case MIB_CHANNELS_DEFAULT_MASK: { getPhy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); mibGet->Param.ChannelsDefaultMask = phyParam.ChannelsMask; break; @@ -3633,89 +3577,89 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t* mibGet ) case MIB_CHANNELS_MASK: { getPhy.Attribute = PHY_CHANNELS_MASK; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); mibGet->Param.ChannelsMask = phyParam.ChannelsMask; break; } case MIB_CHANNELS_NB_TRANS: { - mibGet->Param.ChannelsNbTrans = MacCtx.NvmCtx->MacParams.ChannelsNbTrans; + mibGet->Param.ChannelsNbTrans = Nvm.MacGroup2.MacParams.ChannelsNbTrans; break; } case MIB_MAX_RX_WINDOW_DURATION: { - mibGet->Param.MaxRxWindow = MacCtx.NvmCtx->MacParams.MaxRxWindow; + mibGet->Param.MaxRxWindow = Nvm.MacGroup2.MacParams.MaxRxWindow; break; } case MIB_RECEIVE_DELAY_1: { - mibGet->Param.ReceiveDelay1 = MacCtx.NvmCtx->MacParams.ReceiveDelay1; + mibGet->Param.ReceiveDelay1 = Nvm.MacGroup2.MacParams.ReceiveDelay1; break; } case MIB_RECEIVE_DELAY_2: { - mibGet->Param.ReceiveDelay2 = MacCtx.NvmCtx->MacParams.ReceiveDelay2; + mibGet->Param.ReceiveDelay2 = Nvm.MacGroup2.MacParams.ReceiveDelay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - mibGet->Param.JoinAcceptDelay1 = MacCtx.NvmCtx->MacParams.JoinAcceptDelay1; + mibGet->Param.JoinAcceptDelay1 = Nvm.MacGroup2.MacParams.JoinAcceptDelay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - mibGet->Param.JoinAcceptDelay2 = MacCtx.NvmCtx->MacParams.JoinAcceptDelay2; + mibGet->Param.JoinAcceptDelay2 = Nvm.MacGroup2.MacParams.JoinAcceptDelay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: { - mibGet->Param.ChannelsDefaultDatarate = MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate; + mibGet->Param.ChannelsDefaultDatarate = Nvm.MacGroup2.ChannelsDatarateDefault; break; } case MIB_CHANNELS_DATARATE: { - mibGet->Param.ChannelsDatarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; + mibGet->Param.ChannelsDatarate = Nvm.MacGroup1.ChannelsDatarate; break; } case MIB_CHANNELS_DEFAULT_TX_POWER: { - mibGet->Param.ChannelsDefaultTxPower = MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower; + mibGet->Param.ChannelsDefaultTxPower = Nvm.MacGroup2.ChannelsTxPowerDefault; break; } case MIB_CHANNELS_TX_POWER: { - mibGet->Param.ChannelsTxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; + mibGet->Param.ChannelsTxPower = Nvm.MacGroup1.ChannelsTxPower; break; } case MIB_SYSTEM_MAX_RX_ERROR: { - mibGet->Param.SystemMaxRxError = MacCtx.NvmCtx->MacParams.SystemMaxRxError; + mibGet->Param.SystemMaxRxError = Nvm.MacGroup2.MacParams.SystemMaxRxError; break; } case MIB_MIN_RX_SYMBOLS: { - mibGet->Param.MinRxSymbols = MacCtx.NvmCtx->MacParams.MinRxSymbols; + mibGet->Param.MinRxSymbols = Nvm.MacGroup2.MacParams.MinRxSymbols; break; } case MIB_ANTENNA_GAIN: { - mibGet->Param.AntennaGain = MacCtx.NvmCtx->MacParams.AntennaGain; + mibGet->Param.AntennaGain = Nvm.MacGroup2.MacParams.AntennaGain; break; } case MIB_NVM_CTXS: { - mibGet->Param.Contexts = GetCtxs( ); + mibGet->Param.Contexts = GetNvmData( ); break; } case MIB_DEFAULT_ANTENNA_GAIN: { - mibGet->Param.DefaultAntennaGain = MacCtx.NvmCtx->MacParamsDefaults.AntennaGain; + mibGet->Param.DefaultAntennaGain = Nvm.MacGroup2.MacParamsDefaults.AntennaGain; break; } case MIB_LORAWAN_VERSION: { - mibGet->Param.LrWanVersion.LoRaWan = MacCtx.NvmCtx->Version; + mibGet->Param.LrWanVersion.LoRaWan = Nvm.MacGroup2.Version; mibGet->Param.LrWanVersion.LoRaWanRegion = RegionGetVersion( ); break; } @@ -3754,7 +3698,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { if( mibSet->Param.NetworkActivation != ACTIVATION_TYPE_OTAA ) { - MacCtx.NvmCtx->NetworkActivation = mibSet->Param.NetworkActivation; + Nvm.MacGroup2.NetworkActivation = mibSet->Param.NetworkActivation; } else { // Do not allow to set ACTIVATION_TYPE_OTAA since the MAC will set it automatically after a successful join process. @@ -3780,17 +3724,17 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } case MIB_ADR: { - MacCtx.NvmCtx->AdrCtrlOn = mibSet->Param.AdrEnable; + Nvm.MacGroup2.AdrCtrlOn = mibSet->Param.AdrEnable; break; } case MIB_NET_ID: { - MacCtx.NvmCtx->NetID = mibSet->Param.NetID; + Nvm.MacGroup2.NetID = mibSet->Param.NetID; break; } case MIB_DEV_ADDR: { - MacCtx.NvmCtx->DevAddr = mibSet->Param.DevAddr; + Nvm.MacGroup2.DevAddr = mibSet->Param.DevAddr; break; } case MIB_APP_KEY: @@ -3823,7 +3767,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } break; } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* ST_WORKAROUND: integrate 1.1.x keys only if required */ case MIB_J_S_INT_KEY: { if( mibSet->Param.JSIntKey != NULL ) @@ -3946,6 +3890,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } break; } +#if ( LORAMAC_MAX_MC_CTX > 0 ) /* ST_WORKAROUND: reduced LORAMAC_MAX_MC_CTX */ case MIB_MC_KEY_0: { if( mibSet->Param.McKey0 != NULL ) @@ -3991,6 +3936,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } break; } +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) case MIB_MC_KEY_1: { @@ -4037,6 +3983,8 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } break; } +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) case MIB_MC_KEY_2: { if( mibSet->Param.McKey2 != NULL ) @@ -4082,6 +4030,8 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } break; } +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) case MIB_MC_KEY_3: { if( mibSet->Param.McKey3 != NULL ) @@ -4127,40 +4077,42 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } break; } -#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 3 */ case MIB_PUBLIC_NETWORK: { - MacCtx.NvmCtx->PublicNetwork = mibSet->Param.EnablePublicNetwork; - Radio.SetPublicNetwork( MacCtx.NvmCtx->PublicNetwork ); + Nvm.MacGroup2.PublicNetwork = mibSet->Param.EnablePublicNetwork; + Radio.SetPublicNetwork( Nvm.MacGroup2.PublicNetwork ); /* ST_WORAROUND_BEGIN: Required to avoid keeping the radio active after init */ Radio.Sleep( ); /* ST_WORKAROUND_END */ break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case MIB_REPEATER_SUPPORT: { - MacCtx.NvmCtx->RepeaterSupport = mibSet->Param.EnableRepeaterSupport; + Nvm.MacGroup2.MacParams.RepeaterSupport = mibSet->Param.EnableRepeaterSupport; break; } + /* ST_WORKAROUND_END */ case MIB_RX2_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; /* ST_WORAROUND_BEGIN: Check also the Rx Frequency parameter */ - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) != true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) != true ) { status = LORAMAC_STATUS_PARAMETER_INVALID; } else { verify.Frequency = mibSet->Param.Rx2Channel.Frequency; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_FREQUENCY ) != true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_FREQUENCY ) != true ) { status = LORAMAC_STATUS_PARAMETER_INVALID; } else { - MacCtx.NvmCtx->MacParams.Rx2Channel = mibSet->Param.Rx2Channel; + Nvm.MacGroup2.MacParams.Rx2Channel = mibSet->Param.Rx2Channel; } } /* ST_WORKAROUND_END */ @@ -4169,11 +4121,11 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_RX2_DEFAULT_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel = mibSet->Param.Rx2DefaultChannel; + Nvm.MacGroup2.MacParamsDefaults.Rx2Channel = mibSet->Param.Rx2DefaultChannel; } else { @@ -4184,13 +4136,13 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_RXC_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.RxCChannel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { - MacCtx.NvmCtx->MacParams.RxCChannel = mibSet->Param.RxCChannel; + Nvm.MacGroup2.MacParams.RxCChannel = mibSet->Param.RxCChannel; - if( ( MacCtx.NvmCtx->DeviceClass == CLASS_C ) && ( MacCtx.NvmCtx->NetworkActivation != ACTIVATION_TYPE_NONE ) ) + if( ( Nvm.MacGroup2.DeviceClass == CLASS_C ) && ( Nvm.MacGroup2.NetworkActivation != ACTIVATION_TYPE_NONE ) ) { // We can only compute the RX window parameters directly, if we are already // in class c mode and joined. We cannot setup an RX window in case of any other @@ -4210,11 +4162,11 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_RXC_DEFAULT_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.RxCChannel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.RxCChannel = mibSet->Param.RxCDefaultChannel; + Nvm.MacGroup2.MacParamsDefaults.RxCChannel = mibSet->Param.RxCDefaultChannel; } else { @@ -4227,7 +4179,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsDefaultMask; chanMaskSet.ChannelsMaskType = CHANNELS_DEFAULT_MASK; - if( RegionChanMaskSet( MacCtx.NvmCtx->Region, &chanMaskSet ) == false ) + if( RegionChanMaskSet( Nvm.MacGroup2.Region, &chanMaskSet ) == false ) { status = LORAMAC_STATUS_PARAMETER_INVALID; } @@ -4238,7 +4190,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; chanMaskSet.ChannelsMaskType = CHANNELS_MASK; - if( RegionChanMaskSet( MacCtx.NvmCtx->Region, &chanMaskSet ) == false ) + if( RegionChanMaskSet( Nvm.MacGroup2.Region, &chanMaskSet ) == false ) { status = LORAMAC_STATUS_PARAMETER_INVALID; } @@ -4249,7 +4201,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) if( ( mibSet->Param.ChannelsNbTrans >= 1 ) && ( mibSet->Param.ChannelsNbTrans <= 15 ) ) { - MacCtx.NvmCtx->MacParams.ChannelsNbTrans = mibSet->Param.ChannelsNbTrans; + Nvm.MacGroup2.MacParams.ChannelsNbTrans = mibSet->Param.ChannelsNbTrans; } else { @@ -4259,36 +4211,36 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } case MIB_MAX_RX_WINDOW_DURATION: { - MacCtx.NvmCtx->MacParams.MaxRxWindow = mibSet->Param.MaxRxWindow; + Nvm.MacGroup2.MacParams.MaxRxWindow = mibSet->Param.MaxRxWindow; break; } case MIB_RECEIVE_DELAY_1: { - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; break; } case MIB_RECEIVE_DELAY_2: { - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - MacCtx.NvmCtx->MacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1; + Nvm.MacGroup2.MacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - MacCtx.NvmCtx->MacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2; + Nvm.MacGroup2.MacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: { verify.DatarateParams.Datarate = mibSet->Param.ChannelsDefaultDatarate; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_DEF_TX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_DEF_TX_DR ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate = verify.DatarateParams.Datarate; + Nvm.MacGroup2.ChannelsDatarateDefault = verify.DatarateParams.Datarate; } else { @@ -4299,11 +4251,11 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_CHANNELS_DATARATE: { verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate; - verify.DatarateParams.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; + verify.DatarateParams.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_TX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_TX_DR ) == true ) { - MacCtx.NvmCtx->MacParams.ChannelsDatarate = verify.DatarateParams.Datarate; + Nvm.MacGroup1.ChannelsDatarate = verify.DatarateParams.Datarate; } else { @@ -4315,9 +4267,9 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { verify.TxPower = mibSet->Param.ChannelsDefaultTxPower; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_DEF_TX_POWER ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_DEF_TX_POWER ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower = verify.TxPower; + Nvm.MacGroup2.ChannelsTxPowerDefault = verify.TxPower; } else { @@ -4329,9 +4281,9 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { verify.TxPower = mibSet->Param.ChannelsTxPower; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_TX_POWER ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_TX_POWER ) == true ) { - MacCtx.NvmCtx->MacParams.ChannelsTxPower = verify.TxPower; + Nvm.MacGroup1.ChannelsTxPower = verify.TxPower; } else { @@ -4341,29 +4293,29 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } case MIB_SYSTEM_MAX_RX_ERROR: { - MacCtx.NvmCtx->MacParams.SystemMaxRxError = MacCtx.NvmCtx->MacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError; + Nvm.MacGroup2.MacParams.SystemMaxRxError = Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError; break; } case MIB_MIN_RX_SYMBOLS: { - MacCtx.NvmCtx->MacParams.MinRxSymbols = MacCtx.NvmCtx->MacParamsDefaults.MinRxSymbols = mibSet->Param.MinRxSymbols; + Nvm.MacGroup2.MacParams.MinRxSymbols = Nvm.MacGroup2.MacParamsDefaults.MinRxSymbols = mibSet->Param.MinRxSymbols; break; } case MIB_ANTENNA_GAIN: { - MacCtx.NvmCtx->MacParams.AntennaGain = mibSet->Param.AntennaGain; + Nvm.MacGroup2.MacParams.AntennaGain = mibSet->Param.AntennaGain; break; } case MIB_DEFAULT_ANTENNA_GAIN: { - MacCtx.NvmCtx->MacParamsDefaults.AntennaGain = mibSet->Param.DefaultAntennaGain; + Nvm.MacGroup2.MacParamsDefaults.AntennaGain = mibSet->Param.DefaultAntennaGain; break; } case MIB_NVM_CTXS: { if( mibSet->Param.Contexts != 0 ) { - status = RestoreCtxs( mibSet->Param.Contexts ); + status = RestoreNvmData( mibSet->Param.Contexts ); } else { @@ -4375,7 +4327,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { if( mibSet->Param.AbpLrWanVersion.Fields.Minor <= 1 ) { - MacCtx.NvmCtx->Version = mibSet->Param.AbpLrWanVersion; + Nvm.MacGroup2.Version = mibSet->Param.AbpLrWanVersion; if( LORAMAC_CRYPTO_SUCCESS != LoRaMacCryptoSetLrWanVersion( mibSet->Param.AbpLrWanVersion ) ) { @@ -4394,8 +4346,6 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) break; } } - EventRegionNvmCtxChanged( ); - EventMacNvmCtxChanged( ); return status; } @@ -4414,9 +4364,7 @@ LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) channelAdd.NewChannel = ¶ms; channelAdd.ChannelId = id; - - EventRegionNvmCtxChanged( ); - return RegionChannelAdd( MacCtx.NvmCtx->Region, &channelAdd ); + return RegionChannelAdd( Nvm.MacGroup2.Region, &channelAdd ); } LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) @@ -4433,12 +4381,10 @@ LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) channelRemove.ChannelId = id; - if( RegionChannelsRemove( MacCtx.NvmCtx->Region, &channelRemove ) == false ) + if( RegionChannelsRemove( Nvm.MacGroup2.Region, &channelRemove ) == false ) { return LORAMAC_STATUS_PARAMETER_INVALID; } - - EventRegionNvmCtxChanged( ); return LORAMAC_STATUS_OK; } @@ -4454,15 +4400,26 @@ LoRaMacStatus_t LoRaMacMcChannelSetup( McChannelParams_t *channel ) return LORAMAC_STATUS_MC_GROUP_UNDEFINED; } - MacCtx.NvmCtx->MulticastChannelList[channel->GroupID].ChannelParams = *channel; + Nvm.MacGroup2.MulticastChannelList[channel->GroupID].ChannelParams = *channel; if( channel->IsRemotelySetup == true ) { -#if ( LORAMAC_MAX_MC_CTX == 1 ) - const KeyIdentifier_t mcKeys[LORAMAC_MAX_MC_CTX] = { MC_KEY_0 }; -#else /* LORAMAC_MAX_MC_CTX > 1 */ - const KeyIdentifier_t mcKeys[LORAMAC_MAX_MC_CTX] = { MC_KEY_0, MC_KEY_1, MC_KEY_2, MC_KEY_3 }; -#endif /* LORAMAC_MAX_MC_CTX */ + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ + const KeyIdentifier_t mcKeys[LORAMAC_MAX_MC_CTX] = { +#if ( LORAMAC_MAX_MC_CTX > 0 ) + MC_KEY_0 +#endif /* LORAMAC_MAX_MC_CTX > 0 */ +#if ( LORAMAC_MAX_MC_CTX > 1 ) + , MC_KEY_1 +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) + , MC_KEY_2 +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) + , MC_KEY_3 +#endif /* LORAMAC_MAX_MC_CTX > 3 */ + }; + /* ST_WORKAROUND_END */ if( LoRaMacCryptoSetKey( mcKeys[channel->GroupID], channel->McKeys.McKeyE ) != LORAMAC_CRYPTO_SUCCESS ) { return LORAMAC_STATUS_CRYPTO_ERROR; @@ -4475,13 +4432,36 @@ LoRaMacStatus_t LoRaMacMcChannelSetup( McChannelParams_t *channel ) } else { -#if ( LORAMAC_MAX_MC_CTX == 1 ) - const KeyIdentifier_t mcAppSKeys[LORAMAC_MAX_MC_CTX] = { MC_APP_S_KEY_0 }; - const KeyIdentifier_t mcNwkSKeys[LORAMAC_MAX_MC_CTX] = { MC_NWK_S_KEY_0 }; -#else /* LORAMAC_MAX_MC_CTX > 1 */ - const KeyIdentifier_t mcAppSKeys[LORAMAC_MAX_MC_CTX] = { MC_APP_S_KEY_0, MC_APP_S_KEY_1, MC_APP_S_KEY_2, MC_APP_S_KEY_3 }; - const KeyIdentifier_t mcNwkSKeys[LORAMAC_MAX_MC_CTX] = { MC_NWK_S_KEY_0, MC_NWK_S_KEY_1, MC_NWK_S_KEY_2, MC_NWK_S_KEY_3 }; -#endif /* LORAMAC_MAX_MC_CTX */ + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ + const KeyIdentifier_t mcAppSKeys[LORAMAC_MAX_MC_CTX] = { +#if ( LORAMAC_MAX_MC_CTX > 0 ) + MC_APP_S_KEY_0 +#endif /* LORAMAC_MAX_MC_CTX > 0 */ +#if ( LORAMAC_MAX_MC_CTX > 1 ) + , MC_APP_S_KEY_1 +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) + , MC_APP_S_KEY_2 +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) + , MC_APP_S_KEY_3 +#endif /* LORAMAC_MAX_MC_CTX > 3 */ + }; + const KeyIdentifier_t mcNwkSKeys[LORAMAC_MAX_MC_CTX] = { +#if ( LORAMAC_MAX_MC_CTX > 0 ) + MC_NWK_S_KEY_0 +#endif /* LORAMAC_MAX_MC_CTX > 0 */ +#if ( LORAMAC_MAX_MC_CTX > 1 ) + , MC_NWK_S_KEY_1 +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) + , MC_NWK_S_KEY_2 +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) + , MC_NWK_S_KEY_3 +#endif /* LORAMAC_MAX_MC_CTX > 3 */ + }; + /* ST_WORKAROUND_END */ if( LORAMAC_CRYPTO_SUCCESS != LoRaMacCryptoSetKey( mcAppSKeys[channel->GroupID], channel->McKeys.Session.McAppSKey ) ) { return LORAMAC_STATUS_CRYPTO_ERROR; @@ -4495,14 +4475,11 @@ LoRaMacStatus_t LoRaMacMcChannelSetup( McChannelParams_t *channel ) if( channel->Class == CLASS_B ) { // Calculate class b parameters - LoRaMacClassBSetMulticastPeriodicity( &MacCtx.NvmCtx->MulticastChannelList[channel->GroupID] ); + LoRaMacClassBSetMulticastPeriodicity( &Nvm.MacGroup2.MulticastChannelList[channel->GroupID] ); } // Reset multicast channel downlink counter to initial value. - *MacCtx.NvmCtx->MulticastChannelList[channel->GroupID].DownLinkCounter = FCNT_DOWN_INITAL_VALUE; - - EventMacNvmCtxChanged( ); - EventRegionNvmCtxChanged( ); + *Nvm.MacGroup2.MulticastChannelList[channel->GroupID].DownLinkCounter = FCNT_DOWN_INITAL_VALUE; return LORAMAC_STATUS_OK; } @@ -4514,7 +4491,7 @@ LoRaMacStatus_t LoRaMacMcChannelDelete( AddressIdentifier_t groupID ) } if( ( groupID >= LORAMAC_MAX_MC_CTX ) || - ( MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) + ( Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) { return LORAMAC_STATUS_MC_GROUP_UNDEFINED; } @@ -4524,10 +4501,7 @@ LoRaMacStatus_t LoRaMacMcChannelDelete( AddressIdentifier_t groupID ) // Set all channel fields with 0 memset1( ( uint8_t* )&channel, 0, sizeof( McChannelParams_t ) ); - MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams = channel; - - EventMacNvmCtxChanged( ); - EventRegionNvmCtxChanged( ); + Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams = channel; return LORAMAC_STATUS_OK; } @@ -4535,7 +4509,7 @@ uint8_t LoRaMacMcChannelGetGroupId( uint32_t mcAddress ) { for( uint8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - if( mcAddress == MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.Address ) + if( mcAddress == Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.Address ) { return i; } @@ -4552,20 +4526,18 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx return LORAMAC_STATUS_BUSY; } - DeviceClass_t devClass = MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.Class; + DeviceClass_t devClass = Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.Class; if( ( devClass == CLASS_A ) || ( devClass > CLASS_C ) ) { return LORAMAC_STATUS_PARAMETER_INVALID; } if( ( groupID >= LORAMAC_MAX_MC_CTX ) || - ( MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) + ( Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) { return LORAMAC_STATUS_MC_GROUP_UNDEFINED; } - /* ST_WORAROUND_BEGIN: only clean one bit */ - *status &= 0xEF; // groupID OK - /* ST_WORAROUND_END */ + *status &= 0x0F; // groupID OK VerifyParams_t verify; // Check datarate @@ -4577,9 +4549,9 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx { verify.DatarateParams.Datarate = rxParams->ClassC.Datarate; } - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { *status &= 0xFB; // datarate OK } @@ -4593,7 +4565,7 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx { verify.Frequency = rxParams->ClassC.Frequency; } - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_FREQUENCY ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_FREQUENCY ) == true ) { *status &= 0xF7; // frequency OK } @@ -4601,11 +4573,8 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx if( *status == ( groupID & 0x03 ) ) { // Apply parameters - MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.RxParams = *rxParams; + Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.RxParams = *rxParams; } - - EventMacNvmCtxChanged( ); - EventRegionNvmCtxChanged( ); return LORAMAC_STATUS_OK; } @@ -4650,7 +4619,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) ResetMacParameters( ); - MacCtx.NvmCtx->MacParams.ChannelsDatarate = RegionAlternateDr( MacCtx.NvmCtx->Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR ); + Nvm.MacGroup1.ChannelsDatarate = RegionAlternateDr( Nvm.MacGroup2.Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR ); queueElement.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; @@ -4659,7 +4628,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) if( status != LORAMAC_STATUS_OK ) { // Revert back the previous datarate ( mainly used for US915 like regions ) - MacCtx.NvmCtx->MacParams.ChannelsDatarate = RegionAlternateDr( MacCtx.NvmCtx->Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR_RESTORE ); + Nvm.MacGroup1.ChannelsDatarate = RegionAlternateDr( Nvm.MacGroup2.Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR_RESTORE ); } break; } @@ -4696,7 +4665,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) } case MLME_PING_SLOT_INFO: { - if( MacCtx.NvmCtx->DeviceClass == CLASS_A ) + if( Nvm.MacGroup2.DeviceClass == CLASS_A ) { uint8_t value = mlmeRequest->Req.PingSlotInfo.PingSlot.Value; @@ -4758,11 +4727,11 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) else { LoRaMacConfirmQueueAdd( &queueElement ); - EventMacNvmCtxChanged( ); } return status; } +/* ST_WORKAROUND_BEGIN: Update MCPS request with new input parameter to allow delayed tx */ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest, bool allowDelayedTx ) { GetPhyParams_t getPhy; @@ -4771,7 +4740,9 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest, bool allowDelayedTx LoRaMacHeader_t macHdr; VerifyParams_t verify; uint8_t fPort = 0; - void* fBuffer; + /* ST_WORKAROUND_BEGIN: remove GCC9 warning */ + void* fBuffer = NULL; + /* ST_WORKAROUND_END */ uint16_t fBufferSize; int8_t datarate = DR_0; bool readyToSend = false; @@ -4835,22 +4806,22 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest, bool allowDelayedTx // Get the minimum possible datarate getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); // Apply the minimum possible datarate. // Some regions have limitations for the minimum datarate. datarate = MAX( datarate, ( int8_t )phyParam.Value ); if( readyToSend == true ) { - if( MacCtx.NvmCtx->AdrCtrlOn == false ) + if( Nvm.MacGroup2.AdrCtrlOn == false ) { verify.DatarateParams.Datarate = datarate; - verify.DatarateParams.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; + verify.DatarateParams.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_TX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_TX_DR ) == true ) { - MacCtx.NvmCtx->MacParams.ChannelsDatarate = verify.DatarateParams.Datarate; + Nvm.MacGroup1.ChannelsDatarate = verify.DatarateParams.Datarate; } else { @@ -4858,12 +4829,11 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest, bool allowDelayedTx } } - status = Send( &macHdr, fPort, fBuffer, fBufferSize, allowDelayedTx ); + status = Send( &macHdr, fPort, fBuffer, fBufferSize, allowDelayedTx ); /* ST_WORKAROUND: Update Send request with new input parameter to allow delayed tx */ if( status == LORAMAC_STATUS_OK ) { MacCtx.McpsConfirm.McpsRequest = mcpsRequest->Type; MacCtx.MacFlags.Bits.McpsReq = 1; - EventMacNvmCtxChanged( ); } else { @@ -4876,6 +4846,7 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest, bool allowDelayedTx return status; } +/* ST_WORKAROUND_END */ void LoRaMacTestSetDutyCycleOn( bool enable ) { @@ -4883,9 +4854,9 @@ void LoRaMacTestSetDutyCycleOn( bool enable ) verify.DutyCycle = enable; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_DUTY_CYCLE ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_DUTY_CYCLE ) == true ) { - MacCtx.NvmCtx->DutyCycleOn = enable; + Nvm.MacGroup2.DutyCycleOn = enable; } } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.h index 6da1300d..78576965 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMac.h @@ -36,87 +36,32 @@ * layer and the supported features. * \{ * - * \example classA/B-L072Z-LRWAN1/main.c - * LoRaWAN class A application example for the B-L072Z-LRWAN1. + * \example periodic-uplink-lpp/B-L072Z-LRWAN1/main.c + * LoRaWAN class A/B/C application example for the B-L072Z-LRWAN1. * - * \example classB/B-L072Z-LRWAN1/main.c - * LoRaWAN class B application example for the B-L072Z-LRWAN1. + * \example periodic-uplink-lpp/NAMote72/main.c + * LoRaWAN class A/B/C application example for the NAMote72. * - * \example classC/B-L072Z-LRWAN1/main.c - * LoRaWAN class C application example for the B-L072Z-LRWAN1. + * \example periodic-uplink-lpp/NucleoL073/main.c + * LoRaWAN class A/B/C application example for the NucleoL073. * - * \example classA/NAMote72/main.c - * LoRaWAN class A application example for the NAMote72. + * \example periodic-uplink-lpp/NucleoL152/main.c + * LoRaWAN class A/B/C application example for the NucleoL152. * - * \example classB/NAMote72/main.c - * LoRaWAN class B application example for the NAMote72. + * \example periodic-uplink-lpp/NucleoL476/main.c + * LoRaWAN class A/B/C application example for the NucleoL476. * - * \example classC/NAMote72/main.c - * LoRaWAN class C application example for the NAMote72. + * \example periodic-uplink-lpp/SAMR34/main.c + * LoRaWAN class A/B/C application example for the SAMR34. * - * \example classA/NucleoL073/main.c - * LoRaWAN class A application example for the NucleoL073. + * \example periodic-uplink-lpp/SKiM880B/main.c + * LoRaWAN class A/B/C application example for the SKiM880B. * - * \example classB/NucleoL073/main.c - * LoRaWAN class B application example for the NucleoL073. - * - * \example classC/NucleoL073/main.c - * LoRaWAN class C application example for the NucleoL073. - * - * \example classA/NucleoL152/main.c - * LoRaWAN class A application example for the NucleoL152. - * - * \example classB/NucleoL152/main.c - * LoRaWAN class B application example for the NucleoL152. - * - * \example classC/NucleoL152/main.c - * LoRaWAN class C application example for the NucleoL152. - * - * \example classA/NucleoL476/main.c - * LoRaWAN class A application example for the NucleoL476. - * - * \example classB/NucleoL476/main.c - * LoRaWAN class B application example for the NucleoL476. - * - * \example classC/NucleoL476/main.c - * LoRaWAN class C application example for the NucleoL476. - * - * \example classA/SAMR34/main.c - * LoRaWAN class A application example for the SAMR34. - * - * \example classB/SAMR34/main.c - * LoRaWAN class B application example for the SAMR34. - * - * \example classC/SAMR34/main.c - * LoRaWAN class C application example for the SAMR34. - * - * \example classA/SKiM880B/main.c - * LoRaWAN class A application example for the SKiM880B. - * - * \example classB/SKiM880B/main.c - * LoRaWAN class B application example for the SKiM880B. - * - * \example classC/SKiM880B/main.c - * LoRaWAN class C application example for the SKiM880B. - * - * \example classA/SKiM881AXL/main.c - * LoRaWAN class A application example for the SKiM881AXL. - * - * \example classB/SKiM881AXL/main.c - * LoRaWAN class B application example for the SKiM881AXL. - * - * \example classC/SKiM881AXL/main.c - * LoRaWAN class C application example for the SKiM881AXL. - * - * \example classA/SKiM980A/main.c - * LoRaWAN class A application example for the SKiM980A. - * - * \example classB/SKiM980A/main.c - * LoRaWAN class B application example for the SKiM980A. - * - * \example classC/SKiM980A/main.c - * LoRaWAN class C application example for the SKiM980A. + * \example periodic-uplink-lpp/SKiM881AXL/main.c + * LoRaWAN class A/B/C application example for the SKiM881AXL. * + * \example periodic-uplink-lpp/SKiM980A/main.c + * LoRaWAN class A/B/C application example for the SKiM980A. */ /** ****************************************************************************** @@ -138,11 +83,15 @@ extern "C" #include #include -#include "utilities.h" + #include "timer.h" #include "systime.h" -#include "radio.h" #include "LoRaMacTypes.h" + +#include "RegionNvm.h" +#include "LoRaMacCryptoNvm.h" +#include "secure-element-nvm.h" +#include "LoRaMacClassBNvm.h" #include "lorawan_conf.h" /*! @@ -168,7 +117,53 @@ extern "C" /*! * Start value for multicast keys enumeration */ -#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 +#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 + +/*! + * Maximum MAC commands buffer size + */ +#define LORA_MAC_COMMAND_MAX_LENGTH 128 + + +/*! + * Bitmap value + */ +#define LORAMAC_NVM_NOTIFY_FLAG_NONE 0x00 + +/*! + * Bitmap value for the NVM group crypto. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_CRYPTO 0x01 + +/*! + * Bitmap value for the NVM group MAC 1. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 0x02 + +/*! + * Bitmap value for the NVM group MAC 2. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 0x04 + +/*! + * Bitmap value for the NVM group secure element. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT 0x08 + +/*! + * Bitmap value for the NVM group 1 region. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 0x10 + +/*! + * Bitmap value for the NVM group 2 region. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 0x20 + +/*! + * Bitmap value for the NVM group class b. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_CLASS_B 0x40 /*! * End-Device activation type @@ -189,62 +184,6 @@ typedef enum eActivationType ACTIVATION_TYPE_OTAA = 2, }ActivationType_t; -/*! - * LoRaMAC channels parameters definition - */ -typedef union uDrRange -{ - /*! - * Byte-access to the bits - */ - int8_t Value; - /*! - * Structure to store the minimum and the maximum datarate - */ - struct sFields - { - /*! - * Minimum data rate - * - * LoRaWAN Regional Parameters V1.0.2rB - * - * The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details. - */ - int8_t Min : 4; - /*! - * Maximum data rate - * - * LoRaWAN Regional Parameters V1.0.2rB - * - * The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details. - */ - int8_t Max : 4; - }Fields; -}DrRange_t; - -/*! - * LoRaMAC channel definition - */ -typedef struct sChannelParams -{ - /*! - * Frequency in Hz - */ - uint32_t Frequency; - /*! - * Alternative frequency for RX window 1 - */ - uint32_t Rx1Frequency; - /*! - * Data rate definition - */ - DrRange_t DrRange; - /*! - * Band index - */ - uint8_t Band; -}ChannelParams_t; - /*! * LoRaMAC receive window channel parameters */ @@ -299,82 +238,11 @@ typedef enum eLoRaMacRxSlot RX_SLOT_NONE, }LoRaMacRxSlot_t; -/*! - * LoRaMAC structure to hold internal context pointers and its lengths - */ -typedef struct sLoRaMacCtxs -{ - /*! - * \brief Pointer to Mac context - */ - void* MacNvmCtx; - /*! - * \brief Size of Mac context - */ - size_t MacNvmCtxSize; - /*! - * \brief Pointer to region context - */ - void* RegionNvmCtx; - /*! - * \brief Size of region context - */ - size_t RegionNvmCtxSize; - /*! - * \brief Pointer to crypto module context - */ - void* CryptoNvmCtx; - /*! - * \brief Size of crypto module context - */ - size_t CryptoNvmCtxSize; - /*! - * \brief Pointer to secure element driver context - */ - void* SecureElementNvmCtx; - /*! - * \brief Size of secure element driver context - */ - size_t SecureElementNvmCtxSize; - /*! - * \brief Pointer to MAC commands module context - */ - void* CommandsNvmCtx; - /*! - * \brief Size of MAC commands module context - */ - size_t CommandsNvmCtxSize; - /*! - * \brief Pointer to Class B module context - */ - void* ClassBNvmCtx; - /*! - * \brief Size of MAC Class B module context - */ - size_t ClassBNvmCtxSize; - /*! - * \brief Pointer to MLME Confirm queue module context - */ - void* ConfirmQueueNvmCtx; - /*! - * \brief Size of MLME Confirm queue module context - */ - size_t ConfirmQueueNvmCtxSize; -}LoRaMacCtxs_t; - /*! * Global MAC layer parameters */ typedef struct sLoRaMacParams { - /*! - * Channels TX power - */ - int8_t ChannelsTxPower; - /*! - * Channels data rate - */ - int8_t ChannelsDatarate; /*! * System overall timing error in milliseconds. * [-SystemMaxRxError : +SystemMaxRxError] @@ -438,12 +306,33 @@ typedef struct sLoRaMacParams * Antenna gain of the node */ float AntennaGain; + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Indicates if the node supports repeaters */ bool RepeaterSupport; + /* ST_WORKAROUND_END */ }LoRaMacParams_t; +/*! + * Global RX layer status + */ +typedef struct sLoRaMacRxStatus +{ + /* + * Rssi of the received packet + */ + int16_t Rssi; + /* + * Snr of the received packet + */ + int8_t Snr; + /* + * Holds the current rx window slot + */ + LoRaMacRxSlot_t RxSlot; +}LoRaMacRxStatus_t; + /*! * LoRaMAC data structure for a PingSlotInfoReq \ref MLME_PING_SLOT_INFO * @@ -636,6 +525,211 @@ typedef union eLoRaMacFlags_t }Bits; }LoRaMacFlags_t; +/*! + * LoRaMAC region enumeration + */ +typedef enum eLoRaMacRegion +{ + /*! + * AS band on 923MHz + */ + LORAMAC_REGION_AS923, + /*! + * Australian band on 915MHz + */ + LORAMAC_REGION_AU915, + /*! + * Chinese band on 470MHz + */ + LORAMAC_REGION_CN470, + /*! + * Chinese band on 779MHz + */ + LORAMAC_REGION_CN779, + /*! + * European band on 433MHz + */ + LORAMAC_REGION_EU433, + /*! + * European band on 868MHz + */ + LORAMAC_REGION_EU868, + /*! + * South korean band on 920MHz + */ + LORAMAC_REGION_KR920, + /*! + * India band on 865MHz + */ + LORAMAC_REGION_IN865, + /*! + * North american band on 915MHz + */ + LORAMAC_REGION_US915, + /*! + * Russia band on 864MHz + */ + LORAMAC_REGION_RU864, +}LoRaMacRegion_t; + +typedef struct sLoRaMacNvmDataGroup1 +{ + /*! + * Counts the number of missed ADR acknowledgements + */ + uint32_t AdrAckCounter; + /*! + * Last transmission time. + */ + TimerTime_t LastTxDoneTime; + /*! + * Aggregated time off. + */ + TimerTime_t AggregatedTimeOff; + /*! + * Last received Message integrity Code (MIC) + */ + uint32_t LastRxMic; + /*! + * Channels TX power + */ + int8_t ChannelsTxPower; + /*! + * Channels data rate + */ + int8_t ChannelsDatarate; + /*! + * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates + * if the ACK bit must be set for the next transmission + */ + bool SrvAckRequested; + /*! + * CRC32 value of the MacGroup1 data structure. + */ + uint32_t Crc32; +}LoRaMacNvmDataGroup1_t; + +typedef struct sLoRaMacNvmDataGroup2 +{ + /*! + * LoRaMac region. + */ + LoRaMacRegion_t Region; + /*! + * LoRaMac parameters + */ + LoRaMacParams_t MacParams; + /*! + * LoRaMac default parameters + */ + LoRaMacParams_t MacParamsDefaults; + /*! + * Channels TX power + */ + int8_t ChannelsTxPowerDefault; + /*! + * Channels data rate + */ + int8_t ChannelsDatarateDefault; + /*! + * Network ID ( 3 bytes ) + */ + uint32_t NetID; + /*! + * Mote Address + */ + uint32_t DevAddr; + /*! + * Multicast channel list + */ + MulticastCtx_t MulticastChannelList[LORAMAC_MAX_MC_CTX]; + /*! + * Actual device class + */ + DeviceClass_t DeviceClass; + /*! + * Indicates if the node is connected to + * a private or public network + */ + bool PublicNetwork; + /* + * LoRaMac ADR control status + */ + bool AdrCtrlOn; + /*! + * Maximum duty cycle + * \remark Possibility to shutdown the device. + */ + uint8_t MaxDCycle; + /*! + * Enables/Disables duty cycle management (Test only) + */ + bool DutyCycleOn; + /*! + * Aggregated duty cycle management + */ + uint16_t AggregatedDCycle; + /*! + * Stores the time at LoRaMac initialization. + * + * \remark Used for the BACKOFF_DC computation. + */ + SysTime_t InitializationTime; + /*! + * Current LoRaWAN Version + */ + Version_t Version; + /*! + * End-Device network activation + */ + ActivationType_t NetworkActivation; + /*! + * CRC32 value of the MacGroup2 data structure. + */ + uint32_t Crc32; +}LoRaMacNvmDataGroup2_t; + +/*! + * LoRaMAC data structure for non-volatile memory (NVM). + * This structure contains data which must be stored in NVM. + */ +typedef struct sLoRaMacNvmData +{ + /*! + * Parameters related to the crypto layer. Change with every TX/RX + * procedure. + */ + LoRaMacCryptoNvmData_t Crypto; + /*! + * Parameters related to the MAC which change with high probability after + * every TX/RX procedure. + */ + LoRaMacNvmDataGroup1_t MacGroup1; + /*! + * Parameters related to the MAC which do not change very likely with every + * TX/RX procedure. + */ + LoRaMacNvmDataGroup2_t MacGroup2; + /*! + * Parameters related to the secure-element. + */ + SecureElementNvmData_t SecureElement; + /*! + * Parameters related to the regional implementation which change with high + * probability after every TX/RX procedure. + */ + RegionNvmDataGroup1_t RegionGroup1; + /*! + * Parameters related to the regional implementation which do not change + * very likely with every TX/RX procedure. + */ + RegionNvmDataGroup2_t RegionGroup2; + /*! + * Parameters related to class b. + */ + LoRaMacClassBNvmData_t ClassB; +}LoRaMacNvmData_t; + /*! * * \brief LoRaMAC data services @@ -903,18 +997,6 @@ typedef struct sMcpsIndication * Indicates, if data is available */ bool RxData; - /*! - * Rssi of the received packet - */ - int16_t Rssi; - /*! - * Snr of the received packet - */ - int8_t Snr; - /*! - * Receive window - */ - LoRaMacRxSlot_t RxSlot; /*! * Set if an acknowledgement was received */ @@ -1081,7 +1163,7 @@ typedef struct sMlmeReqTxCw /*! * RF output power to set (Only used with new way) */ - uint8_t Power; + int8_t Power; }MlmeReqTxCw_t; /*! @@ -1366,6 +1448,7 @@ typedef enum eMib * LoRaWAN Specification V1.1.0, chapter 6.1.1.3 */ MIB_NWK_KEY, + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) /*! * Join session integrity key @@ -1403,6 +1486,7 @@ typedef enum eMib */ MIB_NWK_S_KEY, #endif /* USE_LRWAN_1_1_X_CRYPTO */ + /* ST_WORKAROUND_END */ /*! * Application session key * @@ -1415,6 +1499,8 @@ typedef enum eMib * LoRaWAN - Secure element specification v1 */ MIB_MC_KE_KEY, + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ +#if ( LORAMAC_MAX_MC_CTX > 0 ) /*! * Multicast root key index 0 * @@ -1433,6 +1519,7 @@ typedef enum eMib * LoRaWAN - Secure element specification v1 */ MIB_MC_NWK_S_KEY_0, +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) /*! * Multicast root key index 1 @@ -1452,6 +1539,8 @@ typedef enum eMib * LoRaWAN - Secure element specification v1 */ MIB_MC_NWK_S_KEY_1, +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) /*! * Multicast root key index 2 * @@ -1470,6 +1559,8 @@ typedef enum eMib * LoRaWAN - Secure element specification v1 */ MIB_MC_NWK_S_KEY_2, +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) /*! * Multicast root key index 3 * @@ -1488,7 +1579,8 @@ typedef enum eMib * LoRaWAN - Secure element specification v1 */ MIB_MC_NWK_S_KEY_3, -#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 3 */ + /* ST_WORKAROUND_END */ /*! * Set the network type to public or private * @@ -1497,6 +1589,7 @@ typedef enum eMib * [true: public network, false: private network] */ MIB_PUBLIC_NETWORK, + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Support the operation with repeaters * @@ -1505,6 +1598,7 @@ typedef enum eMib * [true: repeater support enabled, false: repeater support disabled] */ MIB_REPEATER_SUPPORT, + /* ST_WORKAROUND_END */ /*! * Communication channels. A get request will return a * pointer which references the first entry of the channel list. The @@ -1720,6 +1814,10 @@ typedef enum eMib * The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details. */ MIB_PING_SLOT_DATARATE, + /*! + * Beacon state + */ + MIB_BEACON_STATE, }Mib_t; /*! @@ -1781,6 +1879,7 @@ typedef union uMibParam * Related MIB type: \ref MIB_NWK_KEY */ uint8_t* NwkKey; + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) /*! * Join session integrity key @@ -1820,6 +1919,7 @@ typedef union uMibParam */ uint8_t* NwkSKey; #endif /* USE_LRWAN_1_1_X_CRYPTO */ + /* ST_WORKAROUND_END */ /*! * Application session key * @@ -1910,12 +2010,14 @@ typedef union uMibParam * Related MIB type: \ref MIB_PUBLIC_NETWORK */ bool EnablePublicNetwork; + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Enable or disable repeater support * * Related MIB type: \ref MIB_REPEATER_SUPPORT */ bool EnableRepeaterSupport; + /* ST_WORKAROUND_END */ /*! * LoRaWAN Channel * @@ -2049,11 +2151,12 @@ typedef union uMibParam */ float DefaultAntennaGain; /*! - * Structure holding pointers to internal non-volatile contexts and its lengths. + * Returns a pointer to the structure holding all data which shall be stored + * in the NVM. * * Related MIB type: \ref MIB_NVM_CTXS */ - LoRaMacCtxs_t* Contexts; + LoRaMacNvmData_t* Contexts; /* * LoRaWAN MAC layer operating version when activated by ABP. * @@ -2150,6 +2253,12 @@ typedef union uMibParam * Related MIB type: \ref MIB_PING_SLOT_DATARATE */ int8_t PingSlotDatarate; + /*! + * State of the beaconing mechanism + * + * Related MIB type: \ref MIB_BEACON_STATE + */ + BeaconState_t BeaconState; }MibParam_t; /*! @@ -2300,89 +2409,6 @@ typedef enum eLoRaMacStatus LORAMAC_STATUS_ERROR }LoRaMacStatus_t; -/*! - * LoRaMAC region enumeration - */ -typedef enum eLoRaMacRegion_t -{ - /*! - * AS band on 923MHz - */ - LORAMAC_REGION_AS923 = 0, - /*! - * Australian band on 915MHz - */ - LORAMAC_REGION_AU915, - /*! - * Chinese band on 470MHz - */ - LORAMAC_REGION_CN470, - /*! - * Chinese band on 779MHz - */ - LORAMAC_REGION_CN779, - /*! - * European band on 433MHz - */ - LORAMAC_REGION_EU433, - /*! - * European band on 868MHz - */ - LORAMAC_REGION_EU868, - /*! - * South korean band on 920MHz - */ - LORAMAC_REGION_KR920, - /*! - * India band on 865MHz - */ - LORAMAC_REGION_IN865, - /*! - * North american band on 915MHz - */ - LORAMAC_REGION_US915, - /*! - * Russia band on 864MHz - */ - LORAMAC_REGION_RU864, -}LoRaMacRegion_t; - -/*! - * Enumeration of modules which have a context - */ -typedef enum LoRaMacNvmCtxModule_e -{ - /*! - * Context for the MAC - */ - LORAMAC_NVMCTXMODULE_MAC, - /*! - * Context for the regions - */ - LORAMAC_NVMCTXMODULE_REGION, - /*! - * Context for the crypto module - */ - LORAMAC_NVMCTXMODULE_CRYPTO, - /*! - * Context for the secure element - */ - LORAMAC_NVMCTXMODULE_SECURE_ELEMENT, - /*! - * Context for the command queue - */ - LORAMAC_NVMCTXMODULE_COMMANDS, - /*! - * Context for class b - */ - LORAMAC_NVMCTXMODULE_CLASS_B, - /*! - * Context for the confirm queue - */ - LORAMAC_NVMCTXMODULE_CONFIRM_QUEUE, -}LoRaMacNvmCtxModule_t; - - /*! * LoRaMAC events structure * Used to notify upper layers of MAC events @@ -2400,19 +2426,19 @@ typedef struct sLoRaMacPrimitives * * \param [OUT] MCPS-Indication parameters */ - void ( *MacMcpsIndication )( McpsIndication_t* McpsIndication ); + void ( *MacMcpsIndication )( McpsIndication_t* McpsIndication, LoRaMacRxStatus_t* RxStatus ); /*! * \brief MLME-Confirm primitive * * \param [OUT] MLME-Confirm parameters */ - void ( *MacMlmeConfirm )( MlmeConfirm_t* MlmeConfirm ); + void ( *MacMlmeConfirm )( MlmeConfirm_t* MlmeConfirms ); /*! * \brief MLME-Indication primitive * * \param [OUT] MLME-Indication parameters */ - void ( *MacMlmeIndication )( MlmeIndication_t* MlmeIndication ); + void ( *MacMlmeIndication )( MlmeIndication_t* MlmeIndication, LoRaMacRxStatus_t* RxStatus ); }LoRaMacPrimitives_t; /*! @@ -2429,18 +2455,29 @@ typedef struct sLoRaMacCallback * to measure the battery level] */ uint8_t ( *GetBatteryLevel )( void ); + /* ST_WORKAROUND_BEGIN: Return temperature into Q7.8 instead float */ /*! * \brief Measures the temperature level * * \retval Temperature level */ uint16_t ( *GetTemperatureLevel )( void ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Add unique ID callback */ + /*! + * \brief Get the board 64 bits unique ID + * + * \param [OUT] id unique + */ + void ( *GetUniqueId )(uint8_t *id); + /* ST_WORKAROUND_END */ /*! * \brief Will be called when an attribute has changed in one of the context. * - * \param Context that changed + * \param notifyFlags Bitmap that contains the modules which changed. + * Refer to \ref LoRaMacNvmData_t. */ - void ( *NvmContextChange )( LoRaMacNvmCtxModule_t module ); + void ( *NvmDataChange )( uint16_t notifyFlags ); /*! *\brief Will be called each time a Radio IRQ is handled by the MAC * layer. @@ -2719,6 +2756,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ); */ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ); +/* ST_WORKAROUND_BEGIN: Update Mcps request with new input parameter to allow delayed tx */ /*! * \brief LoRaMAC MCPS-Request * @@ -2752,6 +2790,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ); * \ref LORAMAC_STATUS_LENGTH_ERROR, */ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest, bool allowDelayedTx ); +/* ST_WORKAROUND_END */ /*! * \brief LoRaMAC deinitialization @@ -2765,7 +2804,6 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest, bool allowDelayedTx */ LoRaMacStatus_t LoRaMacDeInitialization( void ); - /*! \} defgroup LORAMAC */ #ifdef __cplusplus diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.c b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.c index 58432324..d9d16896 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.c @@ -28,19 +28,79 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file LoRaMacClassB.c + * @author MCD Application Team + * @brief LoRa MAC Class B layer implementation + ****************************************************************************** + */ #include #include "utilities.h" #include "secure-element.h" #include "LoRaMac.h" -#include "Region.h" #include "LoRaMacClassB.h" +#include "LoRaMacClassBNvm.h" #include "LoRaMacClassBConfig.h" #include "LoRaMacCrypto.h" #include "LoRaMacConfirmQueue.h" +#include "radio.h" +#include "Region.h" #if ( LORAMAC_CLASSB_ENABLED == 1 ) + +/* + * LoRaMac Class B Context structure + */ +typedef struct sLoRaMacClassBCtx +{ + /*! + * Class B ping slot context + */ + PingSlotContext_t PingSlotCtx; + /*! + * Class B beacon context + */ + BeaconContext_t BeaconCtx; + /*! + * State of the beaconing mechanism + */ + BeaconState_t BeaconState; + /*! + * State of the ping slot mechanism + */ + PingSlotState_t PingSlotState; + /*! + * State of the multicast slot mechanism + */ + PingSlotState_t MulticastSlotState; + /*! + * Timer for CLASS B beacon acquisition and tracking. + */ + TimerEvent_t BeaconTimer; + /*! + * Timer for CLASS B ping slot timer. + */ + TimerEvent_t PingSlotTimer; + /*! + * Timer for CLASS B multicast ping slot timer. + */ + TimerEvent_t MulticastSlotTimer; + /*! + * Container for the callbacks related to class b. + */ + LoRaMacClassBCallback_t LoRaMacClassBCallbacks; + /*! + * Data structure which holds the parameters which needs to be set + * in class b operation. + */ + LoRaMacClassBParams_t LoRaMacClassBParams; +} LoRaMacClassBCtx_t; + /*! * Defines the LoRaMac radio events status */ @@ -57,17 +117,18 @@ typedef union uLoRaMacClassBEvents LoRaMacClassBEvents_t LoRaMacClassBEvents = { .Value = 0 }; -/* - * Non-volatile module context. - */ -static LoRaMacClassBNvmCtx_t NvmCtx; - /* * Module context. */ static LoRaMacClassBCtx_t Ctx; +/*! + * Data structure which holds the parameters which needs to be stored + * in the NVM. + */ +static LoRaMacClassBNvmData_t* ClassBNvm; +/* ST_WORKAROUND_BEGIN: Move timer function (ClassB specific) */ /*! * \brief Computes the temperature compensation for a period of time on a * specific temperature. @@ -111,6 +172,7 @@ static TimerTime_t TimerTempCompensation( TimerTime_t period, float temperature // Calculate the resulting period return ( UTIL_TIMER_Time_t ) interim; } +/* ST_WORKAROUND_END */ /*! * Computes the Ping Offset @@ -199,6 +261,7 @@ static uint32_t CalcDownlinkChannelAndFrequency( uint32_t devAddr, TimerTime_t b PhyParam_t phyParam; uint32_t channel = 0; uint8_t nbChannels = 0; + uint8_t offset = 0; // Default initialization - ping slot channels getPhy.Attribute = PHY_PING_SLOT_NB_CHANNELS; @@ -215,9 +278,14 @@ static uint32_t CalcDownlinkChannelAndFrequency( uint32_t devAddr, TimerTime_t b // defined by the calculation below. if( nbChannels > 1 ) { + getPhy.Attribute = PHY_BEACON_CHANNEL_OFFSET; + phyParam = RegionGetPhyParam( *Ctx.LoRaMacClassBParams.LoRaMacRegion, &getPhy ); + offset = ( uint8_t ) phyParam.Value; + // Calculate the channel for the next downlink channel = devAddr + ( beaconTime / ( beaconInterval / 1000 ) ); channel = channel % nbChannels; + channel += offset; } // Calculate the frequency for the next downlink. This holds @@ -225,21 +293,55 @@ static uint32_t CalcDownlinkChannelAndFrequency( uint32_t devAddr, TimerTime_t b return CalcDownlinkFrequency( channel, isBeacon ); } +/*! + * \brief Calculates the correct frequency and opens up the beacon reception window. Please + * note that the variable WindowTimeout and WindowOffset will be updated according + * to the current settings. Also, the function perform a calculation only, when + * Ctx.BeaconCtx.Ctrl.BeaconAcquired OR Ctx.BeaconCtx.Ctrl.AcquisitionPending is + * set to 1. + * + * \param [IN] rxConfig Reception parameters for the beacon window. + * + * \param [IN] currentSymbolTimeout Current symbol timeout. + */ +static void CalculateBeaconRxWindowConfig( RxConfigParams_t* rxConfig, uint16_t currentSymbolTimeout ) +{ + GetPhyParams_t getPhy; + PhyParam_t phyParam; + + rxConfig->WindowTimeout = currentSymbolTimeout; + rxConfig->WindowOffset = 0; + + //if( ( Ctx.BeaconCtx.Ctrl.BeaconAcquired == 1 ) || ( Ctx.BeaconCtx.Ctrl.AcquisitionPending == 1 ) ) + { + // Apply the symbol timeout only if we have acquired the beacon + // Otherwise, take the window enlargement into account + // Read beacon datarate + getPhy.Attribute = PHY_BEACON_CHANNEL_DR; + phyParam = RegionGetPhyParam( *Ctx.LoRaMacClassBParams.LoRaMacRegion, &getPhy ); + + // Calculate downlink symbols + RegionComputeRxWindowParameters( *Ctx.LoRaMacClassBParams.LoRaMacRegion, + ( int8_t )phyParam.Value, // datarate + Ctx.LoRaMacClassBParams.LoRaMacParams->MinRxSymbols, + Ctx.LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError, + rxConfig ); + } +} + /*! * \brief Calculates the correct frequency and opens up the beacon reception window. * * \param [IN] rxTime The reception time which should be setup * * \param [IN] activateDefaultChannel Set to true, if the function shall setup the default channel + * + * \param [IN] symbolTimeout Symbol timeout */ -static void RxBeaconSetup( TimerTime_t rxTime, bool activateDefaultChannel ) +static void RxBeaconSetup( TimerTime_t rxTime, bool activateDefaultChannel, uint16_t symbolTimeout ) { RxBeaconSetup_t rxBeaconSetup; uint32_t frequency = 0; - RxConfigParams_t beaconRxConfig; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - uint16_t windowTimeout = Ctx.BeaconCtx.SymbolTimeout; if( activateDefaultChannel == true ) { @@ -254,10 +356,10 @@ static void RxBeaconSetup( TimerTime_t rxTime, bool activateDefaultChannel ) CLASSB_BEACON_INTERVAL, true ); } - if( Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq == 1 ) + if( ClassBNvm->BeaconCtx.Ctrl.CustomFreq == 1 ) { // Set the frequency from the BeaconFreqReq - frequency = Ctx.NvmCtx->BeaconCtx.Frequency; + frequency = ClassBNvm->BeaconCtx.Frequency; } if( Ctx.BeaconCtx.Ctrl.BeaconChannelSet == 1 ) @@ -267,24 +369,7 @@ static void RxBeaconSetup( TimerTime_t rxTime, bool activateDefaultChannel ) frequency = CalcDownlinkFrequency( Ctx.BeaconCtx.BeaconTimingChannel, true ); } - if( ( Ctx.BeaconCtx.Ctrl.BeaconAcquired == 1 ) || ( Ctx.BeaconCtx.Ctrl.AcquisitionPending == 1 ) ) - { - // Apply the symbol timeout only if we have acquired the beacon - // Otherwise, take the window enlargement into account - // Read beacon datarate - getPhy.Attribute = PHY_BEACON_CHANNEL_DR; - phyParam = RegionGetPhyParam( *Ctx.LoRaMacClassBParams.LoRaMacRegion, &getPhy ); - - // Calculate downlink symbols - RegionComputeRxWindowParameters( *Ctx.LoRaMacClassBParams.LoRaMacRegion, - ( int8_t )phyParam.Value, // datarate - Ctx.LoRaMacClassBParams.LoRaMacParams->MinRxSymbols, - Ctx.LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError, - &beaconRxConfig ); - windowTimeout = beaconRxConfig.WindowTimeout; - } - - rxBeaconSetup.SymbolTimeout = windowTimeout; + rxBeaconSetup.SymbolTimeout = symbolTimeout; rxBeaconSetup.RxTime = rxTime; rxBeaconSetup.Frequency = frequency; @@ -390,7 +475,7 @@ static void InitClassB( void ) LoRaMacClassBEvents.Value = 0; // Init variables to default - memset1( ( uint8_t* ) &NvmCtx, 0, sizeof( LoRaMacClassBNvmCtx_t ) ); + memset1( ( uint8_t* ) ClassBNvm, 0, sizeof( LoRaMacClassBNvmData_t ) ); memset1( ( uint8_t* ) &Ctx.PingSlotCtx, 0, sizeof( PingSlotContext_t ) ); memset1( ( uint8_t* ) &Ctx.BeaconCtx, 0, sizeof( BeaconContext_t ) ); @@ -401,32 +486,31 @@ static void InitClassB( void ) // Setup default ping slot datarate getPhy.Attribute = PHY_PING_SLOT_CHANNEL_DR; phyParam = RegionGetPhyParam( *Ctx.LoRaMacClassBParams.LoRaMacRegion, &getPhy ); - Ctx.NvmCtx->PingSlotCtx.Datarate = (int8_t)( phyParam.Value ); + ClassBNvm->PingSlotCtx.Datarate = ( int8_t )( phyParam.Value ); // Setup default states Ctx.BeaconState = BEACON_STATE_ACQUISITION; Ctx.PingSlotState = PINGSLOT_STATE_CALC_PING_OFFSET; Ctx.MulticastSlotState = PINGSLOT_STATE_CALC_PING_OFFSET; - Ctx.NvmCtx->BeaconCtx.BeaconState = BEACON_STATE_ACQUISITION; } static void InitClassBDefaults( void ) { // This function shall reset the Class B settings to default, // but should keep important configurations - LoRaMacClassBBeaconNvmCtx_t beaconCtx = Ctx.NvmCtx->BeaconCtx; - LoRaMacClassBPingSlotNvmCtx_t pingSlotCtx = Ctx.NvmCtx->PingSlotCtx; + LoRaMacClassBBeaconNvmData_t beaconCtx = ClassBNvm->BeaconCtx; + LoRaMacClassBPingSlotNvmData_t pingSlotCtx = ClassBNvm->PingSlotCtx; InitClassB( ); // Parameters from BeaconFreqReq - Ctx.NvmCtx->BeaconCtx.Frequency = beaconCtx.Frequency; - Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq = beaconCtx.Ctrl.CustomFreq; + ClassBNvm->BeaconCtx.Frequency = beaconCtx.Frequency; + ClassBNvm->BeaconCtx.Ctrl.CustomFreq = beaconCtx.Ctrl.CustomFreq; // Parameters from PingSlotChannelReq - Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq = pingSlotCtx.Ctrl.CustomFreq; - Ctx.NvmCtx->PingSlotCtx.Frequency = pingSlotCtx.Frequency; - Ctx.NvmCtx->PingSlotCtx.Datarate = pingSlotCtx.Datarate; + ClassBNvm->PingSlotCtx.Ctrl.CustomFreq = pingSlotCtx.Ctrl.CustomFreq; + ClassBNvm->PingSlotCtx.Frequency = pingSlotCtx.Frequency; + ClassBNvm->PingSlotCtx.Datarate = pingSlotCtx.Datarate; } static void EnlargeWindowTimeout( void ) @@ -529,71 +613,32 @@ static uint16_t CalcPingPeriod( uint8_t pingNb ) { return CLASSB_BEACON_WINDOW_SLOTS / pingNb; } +#endif /* LORAMAC_CLASSB_ENABLED */ -/* - * Dummy callback in case if the user provides NULL function pointer - */ -static void NvmContextChange( void ) +void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, + LoRaMacClassBNvmData_t* nvm ) { - if( Ctx.LoRaMacClassBNvmEvent != NULL ) +#if ( LORAMAC_CLASSB_ENABLED == 1 ) + // Assign non-volatile context + if( nvm == NULL ) { - Ctx.LoRaMacClassBNvmEvent( ); + return; } -} - -#endif // LORAMAC_CLASSB_ENABLED + ClassBNvm = nvm; -void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, LoRaMacClassBNvmEvent classBNvmCtxChanged ) -{ -#if ( LORAMAC_CLASSB_ENABLED == 1 ) // Store callbacks Ctx.LoRaMacClassBCallbacks = *callbacks; // Store parameter pointers Ctx.LoRaMacClassBParams = *classBParams; - // Assign non-volatile context - Ctx.NvmCtx = &NvmCtx; - - // Assign callback - Ctx.LoRaMacClassBNvmEvent = classBNvmCtxChanged; - // Initialize timers TimerInit( &Ctx.BeaconTimer, LoRaMacClassBBeaconTimerEvent ); TimerInit( &Ctx.PingSlotTimer, LoRaMacClassBPingSlotTimerEvent ); TimerInit( &Ctx.MulticastSlotTimer, LoRaMacClassBMulticastSlotTimerEvent ); InitClassB( ); -#endif // LORAMAC_CLASSB_ENABLED -} - -bool LoRaMacClassBRestoreNvmCtx( void* classBNvmCtx ) -{ -#if ( LORAMAC_CLASSB_ENABLED == 1 ) - // Restore module context - if( classBNvmCtx != NULL ) - { - memcpy1( ( uint8_t* ) &NvmCtx, ( uint8_t* ) classBNvmCtx, sizeof( NvmCtx ) ); - return true; - } - else - { - return false; - } -#else - return true; -#endif // LORAMAC_CLASSB_ENABLED -} - -void* LoRaMacClassBGetNvmCtx( size_t* classBNvmCtxSize ) -{ -#if ( LORAMAC_CLASSB_ENABLED == 1 ) - *classBNvmCtxSize = sizeof( NvmCtx ); - return &NvmCtx; -#else - *classBNvmCtxSize = 0; - return NULL; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBSetBeaconState( BeaconState_t beaconState ) @@ -621,22 +666,21 @@ void LoRaMacClassBSetBeaconState( BeaconState_t beaconState ) Ctx.BeaconState = beaconState; } } - Ctx.NvmCtx->BeaconCtx.BeaconState = Ctx.BeaconState; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBSetPingSlotState( PingSlotState_t pingSlotState ) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) Ctx.PingSlotState = pingSlotState; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBSetMulticastSlotState( PingSlotState_t multicastSlotState ) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) Ctx.MulticastSlotState = multicastSlotState; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } bool LoRaMacClassBIsAcquisitionInProgress( void ) @@ -657,7 +701,7 @@ bool LoRaMacClassBIsAcquisitionInProgress( void ) return false; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBBeaconTimerEvent( void* context ) @@ -671,7 +715,7 @@ void LoRaMacClassBBeaconTimerEvent( void* context ) { Ctx.LoRaMacClassBCallbacks.MacProcessNotify( ); } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } #if ( LORAMAC_CLASSB_ENABLED == 1 ) @@ -679,6 +723,7 @@ static void LoRaMacClassBProcessBeacon( void ) { bool activateTimer = false; TimerTime_t beaconEventTime = 1; + RxConfigParams_t beaconRxConfig; TimerTime_t currentTime = Ctx.BeaconCtx.TimeStamp; // Beacon state machine @@ -700,11 +745,21 @@ static void LoRaMacClassBProcessBeacon( void ) if( Ctx.BeaconCtx.Ctrl.BeaconDelaySet == 1 ) { + // The goal is to calculate beaconRxConfig.WindowTimeout + CalculateBeaconRxWindowConfig( &beaconRxConfig, Ctx.BeaconCtx.SymbolTimeout ); + if( Ctx.BeaconCtx.BeaconTimingDelay > 0 ) { if( SysTimeToMs( Ctx.BeaconCtx.NextBeaconRx ) > currentTime ) { + // Calculate the time when we expect the next beacon beaconEventTime = TimerTempCompensation( SysTimeToMs( Ctx.BeaconCtx.NextBeaconRx ) - currentTime, Ctx.BeaconCtx.Temperature ); + + if( ( int32_t ) beaconEventTime > beaconRxConfig.WindowOffset ) + { + // Apply the offset of the system error respectively beaconing precision setting + beaconEventTime += beaconRxConfig.WindowOffset; + } } else { @@ -726,7 +781,7 @@ static void LoRaMacClassBProcessBeacon( void ) // Don't use the default channel. We know on which // channel the next beacon will be transmitted - RxBeaconSetup( CLASSB_BEACON_RESERVED, false ); + RxBeaconSetup( CLASSB_BEACON_RESERVED, false, beaconRxConfig.WindowTimeout ); } } else @@ -757,12 +812,15 @@ static void LoRaMacClassBProcessBeacon( void ) Ctx.BeaconCtx.Ctrl.AcquisitionPending = 1; beaconEventTime = CLASSB_BEACON_INTERVAL; + // The goal is to calculate beaconRxConfig.WindowTimeout + CalculateBeaconRxWindowConfig( &beaconRxConfig, Ctx.BeaconCtx.SymbolTimeout ); + // Start the beacon acquisition. When the MAC has received a beacon in function // RxBeacon successfully, the next state is BEACON_STATE_LOCKED. If the MAC does not // find a beacon, the state machine will stay in state BEACON_STATE_ACQUISITION. // This state detects that a acquisition was pending previously and will change the next // state to BEACON_STATE_LOST. - RxBeaconSetup( 0, true ); + RxBeaconSetup( 0, true, beaconRxConfig.WindowTimeout ); } break; } @@ -834,11 +892,20 @@ static void LoRaMacClassBProcessBeacon( void ) beaconEventTime = Ctx.BeaconCtx.NextBeaconRxAdjusted - Radio.GetWakeupTime( ); currentTime = TimerGetCurrentTime( ); + // The goal is to calculate beaconRxConfig.WindowTimeout and beaconRxConfig.WindowOffset + CalculateBeaconRxWindowConfig( &beaconRxConfig, Ctx.BeaconCtx.SymbolTimeout ); + if( beaconEventTime > currentTime ) { Ctx.BeaconState = BEACON_STATE_GUARD; beaconEventTime -= currentTime; beaconEventTime = TimerTempCompensation( beaconEventTime, Ctx.BeaconCtx.Temperature ); + + if( ( int32_t ) beaconEventTime > beaconRxConfig.WindowOffset ) + { + // Apply the offset of the system error respectively beaconing precision setting + beaconEventTime += beaconRxConfig.WindowOffset; + } } else { @@ -856,7 +923,7 @@ static void LoRaMacClassBProcessBeacon( void ) // Don't use the default channel. We know on which // channel the next beacon will be transmitted - RxBeaconSetup( CLASSB_BEACON_RESERVED, false ); + RxBeaconSetup( CLASSB_BEACON_RESERVED, false, beaconRxConfig.WindowTimeout ); break; } case BEACON_STATE_LOST: @@ -899,7 +966,7 @@ static void LoRaMacClassBProcessBeacon( void ) TimerStart( &Ctx.BeaconTimer ); } } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ void LoRaMacClassBPingSlotTimerEvent( void* context ) { @@ -910,7 +977,7 @@ void LoRaMacClassBPingSlotTimerEvent( void* context ) { Ctx.LoRaMacClassBCallbacks.MacProcessNotify( ); } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } #if ( LORAMAC_CLASSB_ENABLED == 1 ) @@ -925,21 +992,21 @@ static void LoRaMacClassBProcessPingSlot( void ) { ComputePingOffset( Ctx.BeaconCtx.BeaconTime.Seconds, *Ctx.LoRaMacClassBParams.LoRaMacDevAddr, - Ctx.NvmCtx->PingSlotCtx.PingPeriod, + ClassBNvm->PingSlotCtx.PingPeriod, &( Ctx.PingSlotCtx.PingOffset ) ); Ctx.PingSlotState = PINGSLOT_STATE_SET_TIMER; } // Intentional fall through case PINGSLOT_STATE_SET_TIMER: { - if( CalcNextSlotTime( Ctx.PingSlotCtx.PingOffset, Ctx.NvmCtx->PingSlotCtx.PingPeriod, Ctx.NvmCtx->PingSlotCtx.PingNb, &pingSlotTime ) == true ) + if( CalcNextSlotTime( Ctx.PingSlotCtx.PingOffset, ClassBNvm->PingSlotCtx.PingPeriod, ClassBNvm->PingSlotCtx.PingNb, &pingSlotTime ) == true ) { if( Ctx.BeaconCtx.Ctrl.BeaconAcquired == 1 ) { // Compute the symbol timeout. Apply it only, if the beacon is acquired // Otherwise, take the enlargement of the symbols into account. RegionComputeRxWindowParameters( *Ctx.LoRaMacClassBParams.LoRaMacRegion, - Ctx.NvmCtx->PingSlotCtx.Datarate, + ClassBNvm->PingSlotCtx.Datarate, Ctx.LoRaMacClassBParams.LoRaMacParams->MinRxSymbols, Ctx.LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError, &pingSlotRxConfig ); @@ -960,10 +1027,10 @@ static void LoRaMacClassBProcessPingSlot( void ) } case PINGSLOT_STATE_IDLE: { - uint32_t frequency = Ctx.NvmCtx->PingSlotCtx.Frequency; + uint32_t frequency = ClassBNvm->PingSlotCtx.Frequency; // Apply a custom frequency if the following bit is set - if( Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq == 0 ) + if( ClassBNvm->PingSlotCtx.Ctrl.CustomFreq == 0 ) { // Restore floor plan frequency = CalcDownlinkChannelAndFrequency( *Ctx.LoRaMacClassBParams.LoRaMacDevAddr, Ctx.BeaconCtx.BeaconTime.Seconds, @@ -976,9 +1043,9 @@ static void LoRaMacClassBProcessPingSlot( void ) { Ctx.PingSlotState = PINGSLOT_STATE_RX; - pingSlotRxConfig.Datarate = Ctx.NvmCtx->PingSlotCtx.Datarate; + pingSlotRxConfig.Datarate = ClassBNvm->PingSlotCtx.Datarate; pingSlotRxConfig.DownlinkDwellTime = Ctx.LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime; - pingSlotRxConfig.RepeaterSupport = Ctx.LoRaMacClassBParams.LoRaMacParams->RepeaterSupport; + pingSlotRxConfig.RepeaterSupport = Ctx.LoRaMacClassBParams.LoRaMacParams->RepeaterSupport; /* ST_WORKAROUND: keep repeater feature */ pingSlotRxConfig.Frequency = frequency; pingSlotRxConfig.RxContinuous = false; pingSlotRxConfig.RxSlot = RX_SLOT_WIN_CLASS_B_PING_SLOT; @@ -1010,7 +1077,7 @@ static void LoRaMacClassBProcessPingSlot( void ) } } } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ void LoRaMacClassBMulticastSlotTimerEvent( void* context ) { @@ -1021,7 +1088,7 @@ void LoRaMacClassBMulticastSlotTimerEvent( void* context ) { Ctx.LoRaMacClassBCallbacks.MacProcessNotify( ); } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } #if ( LORAMAC_CLASSB_ENABLED == 1 ) @@ -1049,7 +1116,7 @@ static void LoRaMacClassBProcessMulticastSlot( void ) case PINGSLOT_STATE_CALC_PING_OFFSET: { // Compute all offsets for every multicast slots - for( uint8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) + for( uint8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) /* ST_WORKAROUND: reduced LORAMAC_MAX_MC_CTX */ { ComputePingOffset( Ctx.BeaconCtx.BeaconTime.Seconds, cur->ChannelParams.Address, @@ -1086,7 +1153,7 @@ static void LoRaMacClassBProcessMulticastSlot( void ) if( Ctx.BeaconCtx.Ctrl.BeaconAcquired == 1 ) { RegionComputeRxWindowParameters( *Ctx.LoRaMacClassBParams.LoRaMacRegion, - Ctx.NvmCtx->PingSlotCtx.Datarate, + ClassBNvm->PingSlotCtx.Datarate, Ctx.LoRaMacClassBParams.LoRaMacParams->MinRxSymbols, Ctx.LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError, &multicastSlotRxConfig ); @@ -1133,7 +1200,7 @@ static void LoRaMacClassBProcessMulticastSlot( void ) multicastSlotRxConfig.Datarate = Ctx.PingSlotCtx.NextMulticastChannel->ChannelParams.RxParams.ClassB.Datarate; multicastSlotRxConfig.DownlinkDwellTime = Ctx.LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime; - multicastSlotRxConfig.RepeaterSupport = Ctx.LoRaMacClassBParams.LoRaMacParams->RepeaterSupport; + multicastSlotRxConfig.RepeaterSupport = Ctx.LoRaMacClassBParams.LoRaMacParams->RepeaterSupport; /* ST_WORKAROUND: keep repeater feature */ multicastSlotRxConfig.Frequency = frequency; multicastSlotRxConfig.RxContinuous = false; multicastSlotRxConfig.RxSlot = RX_SLOT_WIN_CLASS_B_MULTICAST_SLOT; @@ -1166,7 +1233,7 @@ static void LoRaMacClassBProcessMulticastSlot( void ) } } } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size ) { @@ -1259,7 +1326,7 @@ bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size ) Ctx.BeaconCtx.Ctrl.BeaconMode = 1; ResetWindowTimeout( ); Ctx.BeaconState = BEACON_STATE_LOCKED; - Ctx.NvmCtx->BeaconCtx.BeaconState = Ctx.BeaconState; + LoRaMacClassBBeaconTimerEvent( NULL ); } } @@ -1267,7 +1334,6 @@ bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size ) if( Ctx.BeaconState == BEACON_STATE_RX ) { Ctx.BeaconState = BEACON_STATE_TIMEOUT; - Ctx.NvmCtx->BeaconCtx.BeaconState = Ctx.BeaconState; LoRaMacClassBBeaconTimerEvent( NULL ); } // When the MAC listens for a beacon, it is not allowed to process any other @@ -1282,7 +1348,7 @@ bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size ) return beaconProcessed; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } bool LoRaMacClassBIsBeaconExpected( void ) @@ -1296,7 +1362,7 @@ bool LoRaMacClassBIsBeaconExpected( void ) return false; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } bool LoRaMacClassBIsPingExpected( void ) @@ -1309,7 +1375,7 @@ bool LoRaMacClassBIsPingExpected( void ) return false; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } bool LoRaMacClassBIsMulticastExpected( void ) @@ -1322,7 +1388,7 @@ bool LoRaMacClassBIsMulticastExpected( void ) return false; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } bool LoRaMacClassBIsAcquisitionPending( void ) @@ -1335,7 +1401,7 @@ bool LoRaMacClassBIsAcquisitionPending( void ) return false; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } bool LoRaMacClassBIsBeaconModeActive( void ) @@ -1349,16 +1415,15 @@ bool LoRaMacClassBIsBeaconModeActive( void ) return false; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBSetPingSlotInfo( uint8_t periodicity ) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) - Ctx.NvmCtx->PingSlotCtx.PingNb = CalcPingNb( periodicity ); - Ctx.NvmCtx->PingSlotCtx.PingPeriod = CalcPingPeriod( Ctx.NvmCtx->PingSlotCtx.PingNb ); - NvmContextChange( ); -#endif // LORAMAC_CLASSB_ENABLED + ClassBNvm->PingSlotCtx.PingNb = CalcPingNb( periodicity ); + ClassBNvm->PingSlotCtx.PingPeriod = CalcPingPeriod( ClassBNvm->PingSlotCtx.PingNb ); +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBHaltBeaconing( void ) @@ -1382,12 +1447,11 @@ void LoRaMacClassBHaltBeaconing( void ) // Halt beacon state machine Ctx.BeaconState = BEACON_STATE_HALT; - Ctx.NvmCtx->BeaconCtx.BeaconState = Ctx.BeaconState; // Halt ping and multicast slot state machines LoRaMacClassBStopRxSlots( ); } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBResumeBeaconing( void ) @@ -1406,10 +1470,9 @@ void LoRaMacClassBResumeBeaconing( void ) Ctx.BeaconState = BEACON_STATE_REACQUISITION; } - Ctx.NvmCtx->BeaconCtx.BeaconState = Ctx.BeaconState; LoRaMacClassBBeaconTimerEvent( NULL ); } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass ) @@ -1417,7 +1480,7 @@ LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass ) #if ( LORAMAC_CLASSB_ENABLED == 1 ) if( nextClass == CLASS_B ) {// Switch to from class a to class b - if( ( Ctx.BeaconCtx.Ctrl.BeaconMode == 1 ) && ( Ctx.NvmCtx->PingSlotCtx.Ctrl.Assigned == 1 ) ) + if( ( Ctx.BeaconCtx.Ctrl.BeaconMode == 1 ) && ( ClassBNvm->PingSlotCtx.Ctrl.Assigned == 1 ) ) { return LORAMAC_STATUS_OK; } @@ -1434,19 +1497,24 @@ LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass ) return LORAMAC_STATUS_SERVICE_UNKNOWN; #else return LORAMAC_STATUS_SERVICE_UNKNOWN; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } LoRaMacStatus_t LoRaMacClassBMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) - LoRaMacStatus_t status; + LoRaMacStatus_t status = LORAMAC_STATUS_OK; switch( mibGet->Type ) { case MIB_PING_SLOT_DATARATE: { - mibGet->Param.PingSlotDatarate = Ctx.NvmCtx->PingSlotCtx.Datarate; + mibGet->Param.PingSlotDatarate = ClassBNvm->PingSlotCtx.Datarate; + break; + } + case MIB_BEACON_STATE: + { + mibGet->Param.BeaconState = Ctx.BeaconState; break; } default: @@ -1458,20 +1526,19 @@ LoRaMacStatus_t LoRaMacClassBMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) return status; #else return LORAMAC_STATUS_SERVICE_UNKNOWN; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } LoRaMacStatus_t LoRaMacMibClassBSetRequestConfirm( MibRequestConfirm_t *mibSet ) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) - LoRaMacStatus_t status; + LoRaMacStatus_t status = LORAMAC_STATUS_OK; switch( mibSet->Type ) { case MIB_PING_SLOT_DATARATE: { - Ctx.NvmCtx->PingSlotCtx.Datarate = mibSet->Param.PingSlotDatarate; - NvmContextChange( ); + ClassBNvm->PingSlotCtx.Datarate = mibSet->Param.PingSlotDatarate; break; } default: @@ -1483,7 +1550,7 @@ LoRaMacStatus_t LoRaMacMibClassBSetRequestConfirm( MibRequestConfirm_t *mibSet ) return status; #else return LORAMAC_STATUS_SERVICE_UNKNOWN; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBPingSlotInfoAns( void ) @@ -1492,10 +1559,9 @@ void LoRaMacClassBPingSlotInfoAns( void ) if( LoRaMacConfirmQueueIsCmdActive( MLME_PING_SLOT_INFO ) == true ) { LoRaMacConfirmQueueSetStatus( LORAMAC_EVENT_INFO_STATUS_OK, MLME_PING_SLOT_INFO ); - Ctx.NvmCtx->PingSlotCtx.Ctrl.Assigned = 1; - NvmContextChange( ); + ClassBNvm->PingSlotCtx.Ctrl.Assigned = 1; } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } uint8_t LoRaMacClassBPingSlotChannelReq( uint8_t datarate, uint32_t frequency ) @@ -1527,22 +1593,21 @@ uint8_t LoRaMacClassBPingSlotChannelReq( uint8_t datarate, uint32_t frequency ) { if( isCustomFreq == true ) { - Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq = 1; - Ctx.NvmCtx->PingSlotCtx.Frequency = frequency; + ClassBNvm->PingSlotCtx.Ctrl.CustomFreq = 1; + ClassBNvm->PingSlotCtx.Frequency = frequency; } else { - Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq = 0; - Ctx.NvmCtx->PingSlotCtx.Frequency = 0; + ClassBNvm->PingSlotCtx.Ctrl.CustomFreq = 0; + ClassBNvm->PingSlotCtx.Frequency = 0; } - Ctx.NvmCtx->PingSlotCtx.Datarate = datarate; - NvmContextChange( ); + ClassBNvm->PingSlotCtx.Datarate = datarate; } return status; #else return 0; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBBeaconTimingAns( uint16_t beaconTimingDelay, uint8_t beaconTimingChannel, TimerTime_t lastRxDone ) @@ -1571,7 +1636,7 @@ void LoRaMacClassBBeaconTimingAns( uint16_t beaconTimingDelay, uint8_t beaconTim Ctx.LoRaMacClassBParams.MlmeConfirm->BeaconTimingDelay = Ctx.BeaconCtx.BeaconTimingDelay; Ctx.LoRaMacClassBParams.MlmeConfirm->BeaconTimingChannel = Ctx.BeaconCtx.BeaconTimingChannel; } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBDeviceTimeAns( void ) @@ -1607,7 +1672,7 @@ void LoRaMacClassBDeviceTimeAns( void ) LoRaMacConfirmQueueSetStatus( LORAMAC_EVENT_INFO_STATUS_OK, MLME_DEVICE_TIME ); } } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } bool LoRaMacClassBBeaconFreqReq( uint32_t frequency ) @@ -1621,22 +1686,20 @@ bool LoRaMacClassBBeaconFreqReq( uint32_t frequency ) if( RegionVerify( *Ctx.LoRaMacClassBParams.LoRaMacRegion, &verify, PHY_FREQUENCY ) == true ) { - Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq = 1; - Ctx.NvmCtx->BeaconCtx.Frequency = frequency; - NvmContextChange( ); + ClassBNvm->BeaconCtx.Ctrl.CustomFreq = 1; + ClassBNvm->BeaconCtx.Frequency = frequency; return true; } } else { - Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq = 0; - NvmContextChange( ); + ClassBNvm->BeaconCtx.Ctrl.CustomFreq = 0; return true; } return false; #else return false; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } TimerTime_t LoRaMacClassBIsUplinkCollision( TimerTime_t txTimeOnAir ) @@ -1660,7 +1723,7 @@ TimerTime_t LoRaMacClassBIsUplinkCollision( TimerTime_t txTimeOnAir ) return 0; #else return 0; -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBStopRxSlots( void ) @@ -1673,13 +1736,13 @@ void LoRaMacClassBStopRxSlots( void ) LoRaMacClassBEvents.Events.PingSlot = 0; LoRaMacClassBEvents.Events.MulticastSlot = 0; CRITICAL_SECTION_END( ); -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBStartRxSlots( void ) { #if ( LORAMAC_CLASSB_ENABLED == 1 ) - if( Ctx.NvmCtx->PingSlotCtx.Ctrl.Assigned == 1 ) + if( ClassBNvm->PingSlotCtx.Ctrl.Assigned == 1 ) { Ctx.PingSlotState = PINGSLOT_STATE_CALC_PING_OFFSET; TimerSetValue( &Ctx.PingSlotTimer, 1 ); @@ -1689,7 +1752,7 @@ void LoRaMacClassBStartRxSlots( void ) TimerSetValue( &Ctx.MulticastSlotTimer, 1 ); TimerStart( &Ctx.MulticastSlotTimer ); } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBSetMulticastPeriodicity( MulticastCtx_t* multicastChannel ) @@ -1700,7 +1763,7 @@ void LoRaMacClassBSetMulticastPeriodicity( MulticastCtx_t* multicastChannel ) multicastChannel->PingNb = CalcPingNb( multicastChannel->ChannelParams.RxParams.ClassB.Periodicity ); multicastChannel->PingPeriod = CalcPingPeriod( multicastChannel->PingNb ); } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } void LoRaMacClassBProcess( void ) @@ -1728,5 +1791,5 @@ void LoRaMacClassBProcess( void ) LoRaMacClassBProcessMulticastSlot( ); } } -#endif // LORAMAC_CLASSB_ENABLED +#endif /* LORAMAC_CLASSB_ENABLED */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.h index b3896bd1..68db8dba 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassB.h @@ -34,6 +34,16 @@ * layer and the supported features. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file LoRaMacClassB.h + * @author MCD Application Team + * @brief LoRa MAC Class B layer implementation + ****************************************************************************** + */ #ifndef __LORAMACCLASSB_H__ #define __LORAMACCLASSB_H__ @@ -45,59 +55,6 @@ extern "C" #include "systime.h" #include "LoRaMacTypes.h" -/*! - * States of the class B beacon acquisition and tracking - */ -typedef enum eBeaconState -{ - /*! - * Initial state to acquire the beacon - */ - BEACON_STATE_ACQUISITION, - /*! - * Beacon acquisition state when a time reference is available - */ - BEACON_STATE_ACQUISITION_BY_TIME, - /*! - * Handles the state when the beacon reception fails - */ - BEACON_STATE_TIMEOUT, - /*! - * Handles the state when the beacon was missed due to an uplink - */ - BEACON_STATE_BEACON_MISSED, - /*! - * Reacquisition state which applies the algorithm to enlarge the reception - * windows - */ - BEACON_STATE_REACQUISITION, - /*! - * The node has locked a beacon successfully - */ - BEACON_STATE_LOCKED, - /*! - * The beacon state machine is stopped due to operations with higher priority - */ - BEACON_STATE_HALT, - /*! - * The node currently operates in the beacon window and is idle. In this - * state, the temperature measurement takes place - */ - BEACON_STATE_IDLE, - /*! - * The node operates in the guard time of class B - */ - BEACON_STATE_GUARD, - /*! - * The node is in receive mode to lock a beacon - */ - BEACON_STATE_RX, - /*! - * The nodes switches the device class - */ - BEACON_STATE_LOST, -}BeaconState_t; - /*! * States of the class B ping slot mechanism */ @@ -227,12 +184,14 @@ typedef struct sBeaconContext */ typedef struct sLoRaMacClassBCallback { + /* ST_WORKAROUND_BEGIN: Return temperature into Q7.8 instead float */ /*! * \brief Measures the temperature level * * \retval Temperature level */ uint16_t ( *GetTemperatureLevel )( void ); + /* ST_WORKAROUND_END */ /*! *\brief Will be called each time a Radio IRQ is handled by the MAC * layer. @@ -287,161 +246,15 @@ typedef struct sLoRaMacClassBParams */ typedef void ( *LoRaMacClassBNvmEvent )( void ); -/* - * LoRaMac Class B Context structure for NVM parameters - * related to ping slots - */ -typedef struct sLoRaMacClassBPingSlotNvmCtx -{ - struct sPingSlotCtrlNvm - { - /*! - * Set when the server assigned a ping slot to the node - */ - uint8_t Assigned : 1; - /*! - * Set when a custom frequency is used - */ - uint8_t CustomFreq : 1; - }Ctrl; - /*! - * Number of ping slots - */ - uint8_t PingNb; - /*! - * Period of the ping slots - */ - uint16_t PingPeriod; - /*! - * Reception frequency of the ping slot windows - */ - uint32_t Frequency; - /*! - * Datarate of the ping slot - */ - int8_t Datarate; -} LoRaMacClassBPingSlotNvmCtx_t; - -/* - * LoRaMac Class B Context structure for NVM parameters - * related to beaconing - */ -typedef struct sLoRaMacClassBBeaconNvmCtx -{ - struct sBeaconCtrlNvm - { - /*! - * Set if the node has a custom frequency for beaconing and ping slots - */ - uint8_t CustomFreq : 1; - }Ctrl; - /*! - * Beacon reception frequency - */ - uint32_t Frequency; - /*! - * State of the beaconing mechanism - */ - BeaconState_t BeaconState; -} LoRaMacClassBBeaconNvmCtx_t; - -/* - * LoRaMac Class B Context structure - */ -typedef struct sLoRaMacClassBNvmCtx -{ - /*! - * Class B ping slot context - */ - LoRaMacClassBPingSlotNvmCtx_t PingSlotCtx; - /*! - * Class B beacon context - */ - LoRaMacClassBBeaconNvmCtx_t BeaconCtx; -} LoRaMacClassBNvmCtx_t; - -/* - * LoRaMac Class B Context structure - */ -typedef struct sLoRaMacClassBCtx -{ - /*! - * Class B ping slot context - */ - PingSlotContext_t PingSlotCtx; - /*! - * Class B beacon context - */ - BeaconContext_t BeaconCtx; - /*! - * State of the beaconing mechanism - */ - BeaconState_t BeaconState; - /*! - * State of the ping slot mechanism - */ - PingSlotState_t PingSlotState; - /*! - * State of the multicast slot mechanism - */ - PingSlotState_t MulticastSlotState; - /*! - * Timer for CLASS B beacon acquisition and tracking. - */ - TimerEvent_t BeaconTimer; - /*! - * Timer for CLASS B ping slot timer. - */ - TimerEvent_t PingSlotTimer; - /*! - * Timer for CLASS B multicast ping slot timer. - */ - TimerEvent_t MulticastSlotTimer; - /*! - * Container for the callbacks related to class b. - */ - LoRaMacClassBCallback_t LoRaMacClassBCallbacks; - /*! - * Data structure which holds the parameters which needs to be set - * in class b operation. - */ - LoRaMacClassBParams_t LoRaMacClassBParams; - /* - * Callback function to notify the upper layer about context change - */ - LoRaMacClassBNvmEvent LoRaMacClassBNvmEvent; - /*! - * Non-volatile module context. - */ - LoRaMacClassBNvmCtx_t* NvmCtx; -} LoRaMacClassBCtx_t; - /*! * \brief Initialize LoRaWAN Class B * * \param [IN] classBParams Information and feedback parameter * \param [IN] callbacks Contains the callback which the Class B implementation needs - * \param [IN] callback function which will be called when the non-volatile context needs to be saved. - */ -void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, LoRaMacClassBNvmEvent classBNvmCtxChanged ); - -/*! - * Restores the internal non-volatile context from passed pointer. - * - * \param [IN] classBNvmCtx - Pointer to non-volatile class B module context to be restored. - * - * \retval - Status of the operation - */ -bool LoRaMacClassBRestoreNvmCtx( void* classBNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param [IN] classBNvmCtxSize - Size of the module non-volatile context - * - * \retval - Points to a structure where the module store its non-volatile context + * \param [IN] nvm Pointer to an external non-volatile memory data structure. */ -void* LoRaMacClassBGetNvmCtx( size_t* classBNvmCtxSize ); +void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, + LoRaMacClassBNvmData_t* nvm ); /*! * \brief Set the state of the beacon state machine diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassBNvm.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassBNvm.h new file mode 100644 index 00000000..dcfc141e --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacClassBNvm.h @@ -0,0 +1,120 @@ +/*! + * \file LoRaMacClassBNvm.h + * + * \brief LoRa MAC Class B non-volatile data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \addtogroup LORAMACCLASSB + * + * \{ + */ +#ifndef __LORAMACCLASSBNVM_H__ +#define __LORAMACCLASSBNVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/*! + * LoRaMac Class B Context structure for NVM parameters + * related to ping slots + */ +typedef struct sLoRaMacClassBPingSlotNvmData +{ + struct sPingSlotCtrlNvm + { + /*! + * Set when the server assigned a ping slot to the node + */ + uint8_t Assigned : 1; + /*! + * Set when a custom frequency is used + */ + uint8_t CustomFreq : 1; + }Ctrl; + /*! + * Number of ping slots + */ + uint8_t PingNb; + /*! + * Period of the ping slots + */ + uint16_t PingPeriod; + /*! + * Reception frequency of the ping slot windows + */ + uint32_t Frequency; + /*! + * Datarate of the ping slot + */ + int8_t Datarate; +} LoRaMacClassBPingSlotNvmData_t; + +/*! + * LoRaMac Class B Context structure for NVM parameters + * related to beaconing + */ +typedef struct sLoRaMacClassBBeaconNvmData +{ + struct sBeaconCtrlNvm + { + /*! + * Set if the node has a custom frequency for beaconing and ping slots + */ + uint8_t CustomFreq : 1; + }Ctrl; + /*! + * Beacon reception frequency + */ + uint32_t Frequency; +} LoRaMacClassBBeaconNvmData_t; + +/*! + * LoRaMac Class B Context structure + */ +typedef struct sLoRaMacClassBNvmData +{ + /*! + * Class B ping slot context + */ + LoRaMacClassBPingSlotNvmData_t PingSlotCtx; + /*! + * Class B beacon context + */ + LoRaMacClassBBeaconNvmData_t BeaconCtx; + /*! + * CRC32 value of the ClassB data structure. + */ + uint32_t Crc32; +} LoRaMacClassBNvmData_t; + +#ifdef __cplusplus +} +#endif + +#endif // __LORAMACCLASSBNVM_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.c b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.c index 6e3f59f8..1306c2ae 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.c @@ -78,15 +78,10 @@ typedef struct sLoRaMacCommandsCtx size_t SerializedCmdsSize; } LoRaMacCommandsCtx_t; -/*! - * Callback function to notify the upper layer about context change - */ -static LoRaMacCommandsNvmEvent CommandsNvmCtxChanged; - /*! * Non-volatile module context. */ -static LoRaMacCommandsCtx_t NvmCtx; +static LoRaMacCommandsCtx_t CommandsCtx; /* Memory management functions */ @@ -119,7 +114,7 @@ static MacCommand_t* MallocNewMacCommandSlot( void ) { uint8_t itr = 0; - while( IsSlotFree( ( const MacCommand_t* )&NvmCtx.MacCommandSlots[itr] ) == false ) + while( IsSlotFree( ( const MacCommand_t* )&CommandsCtx.MacCommandSlots[itr] ) == false ) { itr++; if( itr == NUM_OF_MAC_COMMANDS ) @@ -128,7 +123,7 @@ static MacCommand_t* MallocNewMacCommandSlot( void ) } } - return &NvmCtx.MacCommandSlots[itr]; + return &CommandsCtx.MacCommandSlots[itr]; } /*! @@ -299,50 +294,16 @@ static bool IsSticky( uint8_t cid ) } } -/* - * \brief Wrapper function for the NvmCtx - */ -static void NvmCtxCallback( void ) -{ - if( CommandsNvmCtxChanged != NULL ) - { - CommandsNvmCtxChanged( ); - } -} - -LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged ) +LoRaMacCommandStatus_t LoRaMacCommandsInit( void ) { // Initialize with default - memset1( ( uint8_t* )&NvmCtx, 0, sizeof( NvmCtx ) ); - - LinkedListInit( &NvmCtx.MacCommandList ); + memset1( ( uint8_t* )&CommandsCtx, 0, sizeof( CommandsCtx ) ); - // Assign callback - CommandsNvmCtxChanged = commandsNvmCtxChanged; + LinkedListInit( &CommandsCtx.MacCommandList ); return LORAMAC_COMMANDS_SUCCESS; } -LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx ) -{ - // Restore module context - if( commandsNvmCtx != NULL ) - { - memcpy1( ( uint8_t* )&NvmCtx, ( uint8_t* )commandsNvmCtx, sizeof( NvmCtx ) ); - return LORAMAC_COMMANDS_SUCCESS; - } - else - { - return LORAMAC_COMMANDS_ERROR_NPE; - } -} - -void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize ) -{ - *commandsNvmCtxSize = sizeof( NvmCtx ); - return &NvmCtx; -} - LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize ) { if( payload == NULL ) @@ -360,7 +321,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, siz } // Add it to the list of Mac commands - if( LinkedListAdd( &NvmCtx.MacCommandList, newCmd ) == false ) + if( LinkedListAdd( &CommandsCtx.MacCommandList, newCmd ) == false ) { return LORAMAC_COMMANDS_ERROR; } @@ -371,9 +332,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, siz memcpy1( ( uint8_t* )newCmd->Payload, payload, payloadSize ); newCmd->IsSticky = IsSticky( cid ); - NvmCtx.SerializedCmdsSize += ( CID_FIELD_SIZE + payloadSize ); - - NvmCtxCallback( ); + CommandsCtx.SerializedCmdsSize += ( CID_FIELD_SIZE + payloadSize ); return LORAMAC_COMMANDS_SUCCESS; } @@ -386,12 +345,12 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd ) } // Remove the Mac command element from MacCommandList - if( LinkedListRemove( &NvmCtx.MacCommandList, macCmd ) == false ) + if( LinkedListRemove( &CommandsCtx.MacCommandList, macCmd ) == false ) { return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND; } - NvmCtx.SerializedCmdsSize -= ( CID_FIELD_SIZE + macCmd->PayloadSize ); + CommandsCtx.SerializedCmdsSize -= ( CID_FIELD_SIZE + macCmd->PayloadSize ); // Free the MacCommand Slot if( FreeMacCommandSlot( macCmd ) == false ) @@ -399,8 +358,6 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd ) return LORAMAC_COMMANDS_ERROR; } - NvmCtxCallback( ); - return LORAMAC_COMMANDS_SUCCESS; } @@ -409,7 +366,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetCmd( uint8_t cid, MacCommand_t** macCmd MacCommand_t* curElement; // Start at the head of the list - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; // Loop through all elements until we find the element with the given CID while( ( curElement != NULL ) && ( curElement->CID != cid ) ) @@ -434,7 +391,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveNoneStickyCmds( void ) MacCommand_t* nexElement; // Start at the head of the list - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; // Loop through all elements while( curElement != NULL ) @@ -451,8 +408,6 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveNoneStickyCmds( void ) } } - NvmCtxCallback( ); - return LORAMAC_COMMANDS_SUCCESS; } @@ -462,7 +417,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveStickyAnsCmds( void ) MacCommand_t* nexElement; // Start at the head of the list - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; // Loop through all elements while( curElement != NULL ) @@ -475,8 +430,6 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveStickyAnsCmds( void ) curElement = nexElement; } - NvmCtxCallback( ); - return LORAMAC_COMMANDS_SUCCESS; } @@ -486,13 +439,13 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetSizeSerializedCmds( size_t* size ) { return LORAMAC_COMMANDS_ERROR_NPE; } - *size = NvmCtx.SerializedCmdsSize; + *size = CommandsCtx.SerializedCmdsSize; return LORAMAC_COMMANDS_SUCCESS; } LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer ) { - MacCommand_t* curElement = NvmCtx.MacCommandList.First; + MacCommand_t* curElement = CommandsCtx.MacCommandList.First; MacCommand_t* nextElement; uint8_t itr = 0; @@ -540,7 +493,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending ) return LORAMAC_COMMANDS_ERROR_NPE; } MacCommand_t* curElement; - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; *cmdsPending = false; diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.h index 2452efe7..c6f76aaf 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCommands.h @@ -119,30 +119,9 @@ typedef void ( *LoRaMacCommandsNvmEvent )( void ); /*! * \brief Initialization of LoRaMac MAC commands module * - * \param[IN] commandsNvmCtxChanged - Callback function which will be called when the - * non-volatile context needs to be saved. - * * \retval - Status of the operation */ -LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged ); - -/*! - * Restores the internal non-volatile context from passed pointer. - * - * \param[IN] commandsNvmCtx - Pointer to non-volatile MAC commands module context to be restored. - * - * \retval - Status of the operation - */ -LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param[IN] commandsNvmCtxSize - Size of the module non-volatile context - * - * \retval - Points to a structure where the module store its non-volatile context - */ -void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize ); +LoRaMacCommandStatus_t LoRaMacCommandsInit( void ); /*! * \brief Adds a new MAC command to be sent. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.c b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.c index 1929b03a..3cc85360 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.c @@ -41,7 +41,7 @@ /* * LoRaMac Confirm Queue Context NVM structure */ -typedef struct sLoRaMacConfirmQueueNvmCtx +typedef struct sLoRaMacConfirmQueueNvmData { /*! * MlmeConfirm queue data structure @@ -55,7 +55,7 @@ typedef struct sLoRaMacConfirmQueueNvmCtx * Variable which holds a common status */ LoRaMacEventInfoStatus_t CommonStatus; -} LoRaMacConfirmQueueNvmCtx_t; +} LoRaMacConfirmQueueNvmData_t; /* * LoRaMac Confirm Queue Context structure @@ -74,21 +74,12 @@ typedef struct sLoRaMacConfirmQueueCtx * Pointer to the last element of the ring buffer */ MlmeConfirmQueue_t* BufferEnd; - /* - * Callback function to notify the upper layer about context change - */ - LoRaMacConfirmQueueNvmEvent LoRaMacConfirmQueueNvmEvent; /*! * Non-volatile module context. */ - LoRaMacConfirmQueueNvmCtx_t* ConfirmQueueNvmCtx; + LoRaMacConfirmQueueNvmData_t Nvm; } LoRaMacConfirmQueueCtx_t; -/* - * Non-volatile module context. - */ -static LoRaMacConfirmQueueNvmCtx_t ConfirmQueueNvmCtx; - /* * Module context. */ @@ -96,10 +87,10 @@ static LoRaMacConfirmQueueCtx_t ConfirmQueueCtx; static MlmeConfirmQueue_t* IncreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer ) { - if( bufferPointer == &ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1] ) + if( bufferPointer == &ConfirmQueueCtx.Nvm.MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1] ) { // Reset to the first element - bufferPointer = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue; + bufferPointer = ConfirmQueueCtx.Nvm.MlmeConfirmQueue; } else { @@ -111,10 +102,10 @@ static MlmeConfirmQueue_t* IncreaseBufferPointer( MlmeConfirmQueue_t* bufferPoin static MlmeConfirmQueue_t* DecreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer ) { - if( bufferPointer == ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue ) + if( bufferPointer == ConfirmQueueCtx.Nvm.MlmeConfirmQueue ) { // Reset to the last element - bufferPointer = &ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1]; + bufferPointer = &ConfirmQueueCtx.Nvm.MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1]; } else { @@ -145,12 +136,12 @@ static MlmeConfirmQueue_t* GetElement( Mlme_t request, MlmeConfirmQueue_t* buffe { MlmeConfirmQueue_t* element = bufferStart; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return NULL; } - for( uint8_t elementCnt = 0; elementCnt < ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt; elementCnt++ ) + for( uint8_t elementCnt = 0; elementCnt < ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt; elementCnt++ ) { if( element->Request == request ) { @@ -163,52 +154,26 @@ static MlmeConfirmQueue_t* GetElement( Mlme_t request, MlmeConfirmQueue_t* buffe return NULL; } -void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged ) +void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives ) { ConfirmQueueCtx.Primitives = primitives; - // Assign nvm context - ConfirmQueueCtx.ConfirmQueueNvmCtx = &ConfirmQueueNvmCtx; - // Init counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt = 0; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt = 0; // Init buffer - ConfirmQueueCtx.BufferStart = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue; - ConfirmQueueCtx.BufferEnd = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue; + ConfirmQueueCtx.BufferStart = ConfirmQueueCtx.Nvm.MlmeConfirmQueue; + ConfirmQueueCtx.BufferEnd = ConfirmQueueCtx.Nvm.MlmeConfirmQueue; - memset1( ( uint8_t* )ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue, 0xFF, sizeof( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue ) ); + memset1( ( uint8_t* )ConfirmQueueCtx.Nvm.MlmeConfirmQueue, 0xFF, sizeof( ConfirmQueueCtx.Nvm.MlmeConfirmQueue ) ); // Common status - ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR; - - // Assign callback - ConfirmQueueCtx.LoRaMacConfirmQueueNvmEvent = confirmQueueNvmCtxChanged; -} - -bool LoRaMacConfirmQueueRestoreNvmCtx( void* confirmQueueNvmCtx ) -{ - // Restore module context - if( confirmQueueNvmCtx != NULL ) - { - memcpy1( ( uint8_t* )&ConfirmQueueNvmCtx, ( uint8_t* ) confirmQueueNvmCtx, sizeof( ConfirmQueueNvmCtx ) ); - return true; - } - else - { - return false; - } -} - -void* LoRaMacConfirmQueueGetNvmCtx( size_t* confirmQueueNvmCtxSize ) -{ - *confirmQueueNvmCtxSize = sizeof( ConfirmQueueNvmCtx ); - return &ConfirmQueueNvmCtx; + ConfirmQueueCtx.Nvm.CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR; } bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ) { - if( IsListFull( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListFull( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { // Protect the buffer against overwrites return false; @@ -220,7 +185,7 @@ bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ) ConfirmQueueCtx.BufferEnd->RestrictCommonReadyToHandle = mlmeConfirm->RestrictCommonReadyToHandle; ConfirmQueueCtx.BufferEnd->ReadyToHandle = false; // Increase counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt++; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt++; // Update end pointer ConfirmQueueCtx.BufferEnd = IncreaseBufferPointer( ConfirmQueueCtx.BufferEnd ); @@ -229,13 +194,13 @@ bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ) bool LoRaMacConfirmQueueRemoveLast( void ) { - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return false; } // Increase counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt--; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt--; // Update start pointer ConfirmQueueCtx.BufferEnd = DecreaseBufferPointer( ConfirmQueueCtx.BufferEnd ); @@ -244,13 +209,13 @@ bool LoRaMacConfirmQueueRemoveLast( void ) bool LoRaMacConfirmQueueRemoveFirst( void ) { - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return false; } // Increase counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt--; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt--; // Update start pointer ConfirmQueueCtx.BufferStart = IncreaseBufferPointer( ConfirmQueueCtx.BufferStart ); @@ -261,7 +226,7 @@ void LoRaMacConfirmQueueSetStatus( LoRaMacEventInfoStatus_t status, Mlme_t reque { MlmeConfirmQueue_t* element = NULL; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == false ) { element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd ); if( element != NULL ) @@ -276,7 +241,7 @@ LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatus( Mlme_t request ) { MlmeConfirmQueue_t* element = NULL; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == false ) { element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd ); if( element != NULL ) @@ -291,9 +256,9 @@ void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status ) { MlmeConfirmQueue_t* element = ConfirmQueueCtx.BufferStart; - ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = status; + ConfirmQueueCtx.Nvm.CommonStatus = status; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == false ) { do { @@ -311,7 +276,7 @@ void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status ) LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatusCmn( void ) { - return ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus; + return ConfirmQueueCtx.Nvm.CommonStatus; } bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request ) @@ -325,7 +290,7 @@ bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request ) void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm ) { - uint8_t nbElements = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt; + uint8_t nbElements = ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt; bool readyToHandle = false; MlmeConfirmQueue_t mlmeConfirmToStore; @@ -360,12 +325,12 @@ void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm ) uint8_t LoRaMacConfirmQueueGetCnt( void ) { - return ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt; + return ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt; } bool LoRaMacConfirmQueueIsFull( void ) { - if( IsListFull( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListFull( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return true; } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.h index b572be4f..8adbe4b9 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacConfirmQueue.h @@ -78,39 +78,12 @@ typedef struct sMlmeConfirmQueue bool RestrictCommonReadyToHandle; }MlmeConfirmQueue_t; -/*! - * Signature of callback function to be called by this module when the - * non-volatile needs to be saved. - */ -typedef void ( *LoRaMacConfirmQueueNvmEvent )( void ); - /*! * \brief Initializes the confirm queue * * \param [IN] primitives - Pointer to the LoRaMac primitives. - * - * \param [IN] confirmQueueNvmCtxChanged - Callback function which will be called when the - * non-volatile context needs to be saved. - */ -void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged ); - -/*! - * Restores the internal non-volatile context from passed pointer. - * - * \param [IN] confirmQueueNvmCtx - Pointer to non-volatile class B module context to be restored. - * - * \retval [true - operation was successful, false - operation failed] - */ -bool LoRaMacConfirmQueueRestoreNvmCtx( void* confirmQueueNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param [IN] confirmQueueNvmCtxSize - Size of the module non-volatile context - * - * \retval - Points to a structure where the module store its non-volatile context */ -void* LoRaMacConfirmQueueGetNvmCtx( size_t* confirmQueueNvmCtxSize ); +void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitive ); /*! * \brief Adds an element to the confirm queue. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.c b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.c index 84c8a500..a47731f7 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.c @@ -30,6 +30,16 @@ * * \author Johannes Bruder ( STACKFORCE ) */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file LoRaMacCrypto.c + * @author MCD Application Team + * @brief LoRa MAC layer cryptography implementation + ****************************************************************************** + */ #include #include #include @@ -56,20 +66,12 @@ */ #define MIC_BLOCK_BX_SIZE 16 +/* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ /* * Number of security context entries */ #define NUM_OF_SEC_CTX LORAMAC_MAX_MC_CTX + 1 - -/* - * Size of the module context - */ -#define CRYPTO_CTX_SIZE sizeof( LoRaMacCryptoCtx_t ) - -/* - * Size of the module non volatile context - */ -#define CRYPTO_NVM_CTX_SIZE sizeof( LoRaMacCryptoNvmCtx_t ) +/* ST_WORKAROUND_END */ /* * Maximum size of the message that can be handled by the crypto operations @@ -81,108 +83,6 @@ */ #define CRYPTO_BUFFER_SIZE CRYPTO_MAXMESSAGE_SIZE + MIC_BLOCK_BX_SIZE -/*! - * LoRaWAN Frame counter list. - */ -typedef struct sFCntList -{ - /*! - * Uplink frame counter which is incremented with each uplink. - */ - uint32_t FCntUp; - /*! - * Network downlink frame counter which is incremented with each downlink on FPort 0 - * or when the FPort field is missing. - */ - uint32_t NFCntDown; - /*! - * Application downlink frame counter which is incremented with each downlink - * on a port different than 0. - */ - uint32_t AFCntDown; - /*! - * In case if the device is connected to a LoRaWAN 1.0 Server, - * this counter is used for every kind of downlink frame. - */ - uint32_t FCntDown; - /*! - * Multicast downlink counter for index 0 - */ - uint32_t McFCntDown0; -#if ( LORAMAC_MAX_MC_CTX > 1 ) - /*! - * Multicast downlink counter for index 1 - */ - uint32_t McFCntDown1; - /*! - * Multicast downlink counter for index 2 - */ - uint32_t McFCntDown2; - /*! - * Multicast downlink counter for index 3 - */ - uint32_t McFCntDown3; -#endif /* LORAMAC_MAX_MC_CTX > 1 */ -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - /* - * RJcount1 is a counter incremented with every Rejoin request Type 1 frame transmitted. - */ - uint16_t RJcount1; -#endif -}FCntList_t; - -/* - * LoRaMac Crypto Non Volatile Context structure - */ -typedef struct sLoRaMacCryptoNvmCtx -{ - /* - * Stores the information if the device is connected to a LoRaWAN network - * server with prior to 1.1.0 implementation. - */ - Version_t LrWanVersion; - /* - * Device nonce is a counter starting at 0 when the device is initially - * powered up and incremented with every JoinRequest. - */ - uint16_t DevNonce; - /* - * JoinNonce is a device specific counter value (that never repeats itself) - * provided by the join server and incremented with every JoinAccept message. - */ - uint32_t JoinNonce; - /* - * Frame counter list - */ - FCntList_t FCntList; - /* - * LastDownFCnt stores the information which frame counter was used to unsecure the last frame. - * This information is needed to compute ConfFCnt in B1 block for the MIC. - */ - uint32_t* LastDownFCnt; -}LoRaMacCryptoNvmCtx_t; - -/* - * LoRaMac Crypto Context structure - */ -typedef struct sLoRaMacCryptoCtx -{ -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - /* - * RJcount0 is a counter incremented with every Type 0 or 2 Rejoin frame transmitted. - */ - uint16_t RJcount0; -#endif - /* - * Non volatile module context structure - */ - LoRaMacCryptoNvmCtx_t* NvmCtx; - /* - * Callback function to notify the upper layer about context change - */ - LoRaMacCryptoNvmEvent EventCryptoNvmCtxChanged; -}LoRaMacCryptoCtx_t; - /* * Key-Address item */ @@ -206,38 +106,44 @@ typedef struct sKeyAddr KeyIdentifier_t RootKey; }KeyAddr_t; +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* - *Crypto module context. + * RJcount0 is a counter incremented with every Type 0 or 2 Rejoin frame transmitted. */ -static LoRaMacCryptoCtx_t CryptoCtx; +static uint16_t RJcount0; +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ /* * Non volatile module context. */ -static LoRaMacCryptoNvmCtx_t NvmCryptoCtx; +static LoRaMacCryptoNvmData_t* CryptoNvm; /* * Key-Address list */ static KeyAddr_t KeyAddrList[NUM_OF_SEC_CTX] = { +/* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ +#if ( LORAMAC_MAX_MC_CTX > 0 ) { MULTICAST_0_ADDR, MC_APP_S_KEY_0, MC_NWK_S_KEY_0, MC_KEY_0 }, +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) { MULTICAST_1_ADDR, MC_APP_S_KEY_1, MC_NWK_S_KEY_1, MC_KEY_1 }, +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) { MULTICAST_2_ADDR, MC_APP_S_KEY_2, MC_NWK_S_KEY_2, MC_KEY_2 }, +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) { MULTICAST_3_ADDR, MC_APP_S_KEY_3, MC_NWK_S_KEY_3, MC_KEY_3 }, -#endif /* LORAMAC_MAX_MC_CTX > 1 */ -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#endif /* LORAMAC_MAX_MC_CTX > 3 */ +/* ST_WORKAROUND_END */ +#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* ST_WORKAROUND: integrate 1.1.x keys only if required */ { UNICAST_DEV_ADDR, APP_S_KEY, S_NWK_S_INT_KEY, NO_KEY } #else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ { UNICAST_DEV_ADDR, APP_S_KEY, NWK_S_KEY, NO_KEY } #endif /* USE_LRWAN_1_1_X_CRYPTO */ }; -/* - * Local functions - */ - /* * Encrypts the payload * @@ -295,7 +201,7 @@ static LoRaMacCryptoStatus_t PayloadEncrypt( uint8_t* buffer, int16_t size, KeyI return LORAMAC_CRYPTO_SUCCESS; } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* * Encrypts the FOpts * @@ -320,7 +226,7 @@ static LoRaMacCryptoStatus_t FOptsEncrypt( uint16_t size, uint32_t address, uint aBlock[0] = 0x01; - if( CryptoCtx.NvmCtx->LrWanVersion.Value > 0x01010000 ) + if( CryptoNvm->LrWanVersion.Value > 0x01010000 ) { // Introduced in LoRaWAN 1.1.1 specification switch( fCntID ) @@ -357,7 +263,7 @@ static LoRaMacCryptoStatus_t FOptsEncrypt( uint16_t size, uint32_t address, uint aBlock[12] = ( frameCounter >> 16 ) & 0xFF; aBlock[13] = ( frameCounter >> 24 ) & 0xFF; - if( CryptoCtx.NvmCtx->LrWanVersion.Value > 0x01010000 ) + if( CryptoNvm->LrWanVersion.Value > 0x01010000 ) { // Introduced in LoRaWAN 1.1.1 specification aBlock[15] = 0x01; @@ -377,7 +283,7 @@ static LoRaMacCryptoStatus_t FOptsEncrypt( uint16_t size, uint32_t address, uint return LORAMAC_CRYPTO_SUCCESS; } -#endif +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ /* * Prepares B0 block for cmac computation. @@ -399,21 +305,21 @@ static LoRaMacCryptoStatus_t PrepareB0( uint16_t msgLen, KeyIdentifier_t keyID, } b0[0] = 0x49; -/* ST_WORAROUND_BEGIN: These bytes are only used for the LRWAN 1.1.x */ + /* ST_WORAROUND_BEGIN: These bytes are only used for the LRWAN 1.1.x */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) if( ( isAck == true ) && ( dir == DOWNLINK ) ) { // confFCnt contains the frame counter value modulo 2^16 of the "confirmed" uplink or downlink frame that is being acknowledged uint16_t confFCnt = 0; - confFCnt = ( uint16_t )( CryptoCtx.NvmCtx->FCntList.FCntUp % 65536 ); + confFCnt = ( uint16_t )( CryptoNvm->FCntList.FCntUp % 65536 ); b0[1] = confFCnt & 0xFF; b0[2] = ( confFCnt >> 8 ) & 0xFF; } else #endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ -/* ST_WORAROUND_END */ + /* ST_WORAROUND_END */ { b0[1] = 0x00; b0[2] = 0x00; @@ -527,7 +433,7 @@ static LoRaMacCryptoStatus_t VerifyCmacB0( uint8_t* msg, uint16_t len, KeyIdenti return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* * Prpares B1 block for cmac computation. * @@ -553,7 +459,7 @@ static LoRaMacCryptoStatus_t PrepareB1( uint16_t msgLen, KeyIdentifier_t keyID, if( isAck == true ) { // confFCnt contains the frame counter value modulo 2^16 of the "confirmed" uplink frame that is being acknowledged - uint16_t confFCnt = ( uint16_t )( *CryptoCtx.NvmCtx->LastDownFCnt % 65536 ); + uint16_t confFCnt = ( uint16_t )( *CryptoNvm->LastDownFCnt % 65536 ); b1[1] = confFCnt & 0xFF; b1[2] = ( confFCnt >> 8 ) & 0xFF; } @@ -622,7 +528,7 @@ static LoRaMacCryptoStatus_t ComputeCmacB1( uint8_t* msg, uint16_t len, KeyIdent } return LORAMAC_CRYPTO_SUCCESS; } -#endif +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ /* * Gets security item from list. @@ -653,15 +559,11 @@ static LoRaMacCryptoStatus_t GetKeyAddrItem( AddressIdentifier_t addrID, KeyAddr * \param[IN] deviceNonce - Device nonce * \retval - Status of the operation */ -static LoRaMacCryptoStatus_t DeriveSessionKey10x( KeyIdentifier_t keyID, uint8_t* joinNonce, uint8_t* netID, uint8_t* devNonce ) +static LoRaMacCryptoStatus_t DeriveSessionKey10x( KeyIdentifier_t keyID, uint32_t joinNonce, uint32_t netID, uint16_t devNonce ) { - if( ( joinNonce == 0 ) || ( netID == 0 ) || ( devNonce == 0 ) ) - { - return LORAMAC_CRYPTO_ERROR_NPE; - } - uint8_t compBase[16] = { 0 }; + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ switch( keyID ) { #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) @@ -679,12 +581,20 @@ static LoRaMacCryptoStatus_t DeriveSessionKey10x( KeyIdentifier_t keyID, uint8_t default: return LORAMAC_CRYPTO_ERROR_INVALID_KEY_ID; } + /* ST_WORKAROUND_END */ + + compBase[1] = ( uint8_t )( ( joinNonce >> 0 ) & 0xFF ); + compBase[2] = ( uint8_t )( ( joinNonce >> 8 ) & 0xFF ); + compBase[3] = ( uint8_t )( ( joinNonce >> 16 ) & 0xFF ); + + compBase[4] = ( uint8_t )( ( netID >> 0 ) & 0xFF ); + compBase[5] = ( uint8_t )( ( netID >> 8 ) & 0xFF ); + compBase[6] = ( uint8_t )( ( netID >> 16 ) & 0xFF ); - memcpy1( compBase + 1, joinNonce, 3 ); - memcpy1( compBase + 4, netID, 3 ); - memcpy1( compBase + 7, devNonce, 2 ); + compBase[7] = ( uint8_t )( ( devNonce >> 0 ) & 0xFF ); + compBase[8] = ( uint8_t )( ( devNonce >> 8 ) & 0xFF ); - if( SecureElementDeriveAndStoreKey( CryptoCtx.NvmCtx->LrWanVersion, compBase, NWK_KEY, keyID ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementDeriveAndStoreKey( compBase, NWK_KEY, keyID ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } @@ -692,7 +602,7 @@ static LoRaMacCryptoStatus_t DeriveSessionKey10x( KeyIdentifier_t keyID, uint8_t return LORAMAC_CRYPTO_SUCCESS; } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* * Derives a session key as of LoRaWAN 1.1.0 * @@ -702,9 +612,9 @@ static LoRaMacCryptoStatus_t DeriveSessionKey10x( KeyIdentifier_t keyID, uint8_t * \param[IN] deviceNonce - Device nonce * \retval - Status of the operation */ -static LoRaMacCryptoStatus_t DeriveSessionKey11x( KeyIdentifier_t keyID, uint8_t* joinNonce, uint8_t* joinEUI, uint8_t* devNonce ) +static LoRaMacCryptoStatus_t DeriveSessionKey11x( KeyIdentifier_t keyID, uint32_t joinNonce, uint8_t* joinEUI, uint16_t devNonce ) { - if( ( joinNonce == 0 ) || ( joinEUI == 0 ) || ( devNonce == 0 ) ) + if( joinEUI == 0 ) { return LORAMAC_CRYPTO_ERROR_NPE; } @@ -731,11 +641,16 @@ static LoRaMacCryptoStatus_t DeriveSessionKey11x( KeyIdentifier_t keyID, uint8_t return LORAMAC_CRYPTO_ERROR_INVALID_KEY_ID; } - memcpy1( compBase + 1, joinNonce, 3 ); + compBase[1] = ( uint8_t )( ( joinNonce >> 0 ) & 0xFF ); + compBase[2] = ( uint8_t )( ( joinNonce >> 8 ) & 0xFF ); + compBase[3] = ( uint8_t )( ( joinNonce >> 16 ) & 0xFF ); + memcpyr( compBase + 4, joinEUI, 8 ); - memcpy1( compBase + 12, devNonce, 2 ); - if( SecureElementDeriveAndStoreKey( CryptoCtx.NvmCtx->LrWanVersion, compBase, rootKeyId, keyID ) != SECURE_ELEMENT_SUCCESS ) + compBase[12] = ( uint8_t )( ( devNonce >> 0 ) & 0xFF ); + compBase[13] = ( uint8_t )( ( devNonce >> 8 ) & 0xFF ); + + if( SecureElementDeriveAndStoreKey( compBase, rootKeyId, keyID ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } @@ -773,14 +688,14 @@ static LoRaMacCryptoStatus_t DeriveLifeTimeSessionKey( KeyIdentifier_t keyID, ui memcpyr( compBase + 1, devEUI, 8 ); - if( SecureElementDeriveAndStoreKey( CryptoCtx.NvmCtx->LrWanVersion, compBase, NWK_KEY, keyID ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementDeriveAndStoreKey( compBase, NWK_KEY, keyID ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } return LORAMAC_CRYPTO_SUCCESS; } -#endif +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ /* * Gets the last received frame counter @@ -799,31 +714,37 @@ static LoRaMacCryptoStatus_t GetLastFcntDown( FCntIdentifier_t fCntID, uint32_t* switch( fCntID ) { case N_FCNT_DOWN: - *lastDown = CryptoCtx.NvmCtx->FCntList.NFCntDown; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.NFCntDown; + *lastDown = CryptoNvm->FCntList.NFCntDown; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.NFCntDown; break; case A_FCNT_DOWN: - *lastDown = CryptoCtx.NvmCtx->FCntList.AFCntDown; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.AFCntDown; + *lastDown = CryptoNvm->FCntList.AFCntDown; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.AFCntDown; break; case FCNT_DOWN: - *lastDown = CryptoCtx.NvmCtx->FCntList.FCntDown; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.FCntDown; + *lastDown = CryptoNvm->FCntList.FCntDown; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.FCntDown; break; +#if ( LORAMAC_MAX_MC_CTX > 0 ) case MC_FCNT_DOWN_0: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown0; + *lastDown = CryptoNvm->FCntList.McFCntDown[0]; break; +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) case MC_FCNT_DOWN_1: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown1; + *lastDown = CryptoNvm->FCntList.McFCntDown[1]; break; +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) case MC_FCNT_DOWN_2: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown2; + *lastDown = CryptoNvm->FCntList.McFCntDown[2]; break; +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) case MC_FCNT_DOWN_3: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown3; + *lastDown = CryptoNvm->FCntList.McFCntDown[3]; break; -#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 3 */ default: return LORAMAC_CRYPTO_FAIL_FCNT_ID; } @@ -870,32 +791,37 @@ static void UpdateFCntDown( FCntIdentifier_t fCntID, uint32_t currentDown ) switch( fCntID ) { case N_FCNT_DOWN: - CryptoCtx.NvmCtx->FCntList.NFCntDown = currentDown; + CryptoNvm->FCntList.NFCntDown = currentDown; break; case A_FCNT_DOWN: - CryptoCtx.NvmCtx->FCntList.AFCntDown = currentDown; + CryptoNvm->FCntList.AFCntDown = currentDown; break; case FCNT_DOWN: - CryptoCtx.NvmCtx->FCntList.FCntDown = currentDown; + CryptoNvm->FCntList.FCntDown = currentDown; break; +#if ( LORAMAC_MAX_MC_CTX > 0 ) case MC_FCNT_DOWN_0: - CryptoCtx.NvmCtx->FCntList.McFCntDown0 = currentDown; + CryptoNvm->FCntList.McFCntDown[0] = currentDown; break; +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) case MC_FCNT_DOWN_1: - CryptoCtx.NvmCtx->FCntList.McFCntDown1 = currentDown; + CryptoNvm->FCntList.McFCntDown[1] = currentDown; break; +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) case MC_FCNT_DOWN_2: - CryptoCtx.NvmCtx->FCntList.McFCntDown2 = currentDown; + CryptoNvm->FCntList.McFCntDown[2] = currentDown; break; +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) case MC_FCNT_DOWN_3: - CryptoCtx.NvmCtx->FCntList.McFCntDown3 = currentDown; + CryptoNvm->FCntList.McFCntDown[3] = currentDown; break; -#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 3 */ default: break; } - CryptoCtx.EventCryptoNvmCtxChanged( ); } /*! @@ -903,57 +829,39 @@ static void UpdateFCntDown( FCntIdentifier_t fCntID, uint32_t currentDown ) */ static void ResetFCnts( void ) { + CryptoNvm->FCntList.FCntUp = 0; + CryptoNvm->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.FCntDown; - CryptoCtx.NvmCtx->FCntList.FCntUp = 0; - CryptoCtx.NvmCtx->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.FCntDown; - - CryptoCtx.NvmCtx->FCntList.McFCntDown0 = FCNT_DOWN_INITAL_VALUE; -#if ( LORAMAC_MAX_MC_CTX > 1 ) - CryptoCtx.NvmCtx->FCntList.McFCntDown1 = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.McFCntDown2 = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.McFCntDown3 = FCNT_DOWN_INITAL_VALUE; -#endif /* LORAMAC_MAX_MC_CTX > 1 */ - CryptoCtx.EventCryptoNvmCtxChanged( ); -} - -/* - * Dummy callback in case if the user provides NULL function pointer - */ -static void DummyCB( void ) -{ - return; + for( int32_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) + { + CryptoNvm->FCntList.McFCntDown[i] = FCNT_DOWN_INITAL_VALUE; + } } /* * API functions */ - -LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChanged ) +LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmData_t* nvm ) { - // Assign non volatile context - CryptoCtx.NvmCtx = &NvmCryptoCtx; - - // Assign callback - if( cryptoNvmCtxChanged != 0 ) + if( nvm == NULL ) { - CryptoCtx.EventCryptoNvmCtxChanged = cryptoNvmCtxChanged; - } - else - { - CryptoCtx.EventCryptoNvmCtxChanged = DummyCB; + return LORAMAC_CRYPTO_FAIL_PARAM; } + // Assign non volatile context + CryptoNvm = nvm; + // Initialize with default - memset1( ( uint8_t* )CryptoCtx.NvmCtx, 0, sizeof( LoRaMacCryptoNvmCtx_t ) ); + memset1( ( uint8_t* )CryptoNvm, 0, sizeof( LoRaMacCryptoNvmData_t ) ); // Set default LoRaWAN version - CryptoCtx.NvmCtx->LrWanVersion.Fields.Major = 1; - CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor = 1; - CryptoCtx.NvmCtx->LrWanVersion.Fields.Patch = 1; - CryptoCtx.NvmCtx->LrWanVersion.Fields.Revision = 0; + CryptoNvm->LrWanVersion.Fields.Major = 1; + CryptoNvm->LrWanVersion.Fields.Minor = 1; + CryptoNvm->LrWanVersion.Fields.Patch = 1; + CryptoNvm->LrWanVersion.Fields.Revision = 0; // Reset frame counters ResetFCnts( ); @@ -963,30 +871,10 @@ LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChang LoRaMacCryptoStatus_t LoRaMacCryptoSetLrWanVersion( Version_t version ) { - CryptoCtx.NvmCtx->LrWanVersion = version; + CryptoNvm->LrWanVersion = version; return LORAMAC_CRYPTO_SUCCESS; } -LoRaMacCryptoStatus_t LoRaMacCryptoRestoreNvmCtx( void* cryptoNvmCtx ) -{ - // Restore module context - if( cryptoNvmCtx != 0 ) - { - memcpy1( ( uint8_t* )&NvmCryptoCtx, ( uint8_t* )cryptoNvmCtx, CRYPTO_NVM_CTX_SIZE ); - return LORAMAC_CRYPTO_SUCCESS; - } - else - { - return LORAMAC_CRYPTO_ERROR_NPE; - } -} - -void* LoRaMacCryptoGetNvmCtx( size_t* cryptoNvmCtxSize ) -{ - *cryptoNvmCtxSize = CRYPTO_NVM_CTX_SIZE; - return &NvmCryptoCtx; -} - LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp ) { if( currentUp == NULL ) @@ -994,7 +882,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp ) return LORAMAC_CRYPTO_ERROR_NPE; } - *currentUp = CryptoCtx.NvmCtx->FCntList.FCntUp + 1; + *currentUp = CryptoNvm->FCntList.FCntUp + 1; return LORAMAC_CRYPTO_SUCCESS; } @@ -1042,7 +930,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint16_ } // For LoRaWAN 1.0.X only, check maxFCntGap - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 0 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 0 ) { if( ( ( int64_t )*currentDown - ( int64_t )lastDown ) >= maxFCntGap ) { @@ -1053,6 +941,28 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint16_ return LORAMAC_CRYPTO_SUCCESS; } +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) +LoRaMacCryptoStatus_t LoRaMacCryptoGetRJcount( FCntIdentifier_t fCntID, uint16_t* rJcount ) +{ + if( rJcount == 0 ) + { + return LORAMAC_CRYPTO_ERROR_NPE; + } + switch( fCntID ) + { + case RJ_COUNT_0: + *rJcount = RJcount0 + 1; + break; + case RJ_COUNT_1: + *rJcount = CryptoNvm->FCntList.RJcount1 + 1; + break; + default: + return LORAMAC_CRYPTO_FAIL_FCNT_ID; + } + return LORAMAC_CRYPTO_SUCCESS; +} +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ + LoRaMacCryptoStatus_t LoRaMacCryptoSetMulticastReference( MulticastCtx_t* multicastList ) { if( multicastList == NULL ) @@ -1060,12 +970,11 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSetMulticastReference( MulticastCtx_t* multic return LORAMAC_CRYPTO_ERROR_NPE; } - multicastList[0].DownLinkCounter = &CryptoCtx.NvmCtx->FCntList.McFCntDown0; -#if ( LORAMAC_MAX_MC_CTX > 1 ) - multicastList[1].DownLinkCounter = &CryptoCtx.NvmCtx->FCntList.McFCntDown1; - multicastList[2].DownLinkCounter = &CryptoCtx.NvmCtx->FCntList.McFCntDown2; - multicastList[3].DownLinkCounter = &CryptoCtx.NvmCtx->FCntList.McFCntDown3; -#endif /* LORAMAC_MAX_MC_CTX > 1 */ + for( int32_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) + { + multicastList[i].DownLinkCounter = &CryptoNvm->FCntList.McFCntDown[i]; + } + return LORAMAC_CRYPTO_SUCCESS; } @@ -1078,7 +987,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSetKey( KeyIdentifier_t keyID, uint8_t* key ) if( keyID == APP_KEY ) { // Derive lifetime keys - if( LoRaMacCryptoDeriveMcRootKey( keyID ) != LORAMAC_CRYPTO_SUCCESS ) + if( LoRaMacCryptoDeriveMcRootKey( CryptoNvm->LrWanVersion.Fields.Minor, keyID ) != LORAMAC_CRYPTO_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } @@ -1102,14 +1011,13 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest #if ( USE_RANDOM_DEV_NONCE == 1 ) uint32_t devNonce = 0; SecureElementRandomNumber( &devNonce ); - CryptoCtx.NvmCtx->DevNonce = devNonce; + CryptoNvm->DevNonce = devNonce; #else - CryptoCtx.NvmCtx->DevNonce++; -#endif - CryptoCtx.EventCryptoNvmCtxChanged( ); - macMsg->DevNonce = CryptoCtx.NvmCtx->DevNonce; + CryptoNvm->DevNonce++; +#endif /* USE_RANDOM_DEV_NONCE */ + macMsg->DevNonce = CryptoNvm->DevNonce; -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) // Derive lifetime session keys if( DeriveLifeTimeSessionKey( J_S_INT_KEY, macMsg->DevEUI ) != LORAMAC_CRYPTO_SUCCESS ) { @@ -1119,7 +1027,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest { return LORAMAC_CRYPTO_ERROR; } -#endif +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ // Serialize message if( LoRaMacSerializerJoinRequest( macMsg ) != LORAMAC_SERIALIZER_SUCCESS ) @@ -1142,7 +1050,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest return LORAMAC_CRYPTO_SUCCESS; } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1_t* macMsg ) { if( macMsg == 0 ) @@ -1151,7 +1059,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1 } // Check for RJcount1 overflow - if( CryptoCtx.NvmCtx->FCntList.RJcount1 == 65535 ) + if( CryptoNvm->FCntList.RJcount1 == 65535 ) { return LORAMAC_CRYPTO_ERROR_RJCOUNT1_OVERFLOW; } @@ -1176,8 +1084,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1 } // Increment RJcount1 - CryptoCtx.NvmCtx->FCntList.RJcount1++; - CryptoCtx.EventCryptoNvmCtxChanged( ); + CryptoNvm->FCntList.RJcount1++; return LORAMAC_CRYPTO_SUCCESS; } @@ -1190,7 +1097,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinTy } // Check for RJcount0 overflow - if( CryptoCtx.RJcount0 == 65535 ) + if( RJcount0 == 65535 ) { return LORAMAC_CRYPTO_FAIL_RJCOUNT0_OVERFLOW; } @@ -1215,11 +1122,11 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinTy } // Increment RJcount0 - CryptoCtx.RJcount0++; + RJcount0++; return LORAMAC_CRYPTO_SUCCESS; } -#endif +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReqType, uint8_t* joinEUI, LoRaMacMessageJoinAccept_t* macMsg ) { @@ -1231,33 +1138,33 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq LoRaMacCryptoStatus_t retval = LORAMAC_CRYPTO_ERROR; uint8_t decJoinAccept[LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE] = { 0 }; uint8_t versionMinor = 0; - uint8_t* nonce = ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce; + uint16_t nonce = CryptoNvm->DevNonce; // Nonce selection depending on JoinReqType - // JOIN_REQ : CryptoCtx.NvmCtx->DevNonce - // REJOIN_REQ_0 : CryptoCtx.RJcount0 + // JOIN_REQ : CryptoNvm->DevNonce + // REJOIN_REQ_0 : RJcount0 // REJOIN_REQ_1 : CryptoCtx.RJcount1 - // REJOIN_REQ_2 : CryptoCtx.RJcount0 + // REJOIN_REQ_2 : RJcount0 if( joinReqType == JOIN_REQ ) { // Nothing to be done } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) else { // If Join-accept is a reply to a rejoin, the RJcount(0 or 1) replaces DevNonce in the key derivation process. if( ( joinReqType == REJOIN_REQ_0 ) || ( joinReqType == REJOIN_REQ_2 ) ) { - nonce = ( uint8_t* )&CryptoCtx.RJcount0; + nonce = RJcount0; } else { - nonce = ( uint8_t* )&CryptoCtx.NvmCtx->FCntList.RJcount1; + nonce = CryptoNvm->FCntList.RJcount1; } } -#endif +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ - if( SecureElementProcessJoinAccept( joinReqType, joinEUI, ( int16_t )*nonce, macMsg->Buffer, + if( SecureElementProcessJoinAccept( joinReqType, joinEUI, nonce, macMsg->Buffer, macMsg->BufSize, decJoinAccept, &versionMinor ) != SECURE_ELEMENT_SUCCESS ) { @@ -1272,106 +1179,123 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq return LORAMAC_CRYPTO_ERROR_PARSER; } -#if ( USE_JOIN_NONCE_COUNTER_CHECK == 1 ) - // Check if the JoinNonce is greater as the previous one - uint32_t currentJoinNonce = 0; + uint32_t currentJoinNonce; currentJoinNonce = ( uint32_t )macMsg->JoinNonce[0]; currentJoinNonce |= ( ( uint32_t )macMsg->JoinNonce[1] << 8 ); currentJoinNonce |= ( ( uint32_t )macMsg->JoinNonce[2] << 16 ); - if( currentJoinNonce > CryptoCtx.NvmCtx->JoinNonce ) +#if( USE_JOIN_NONCE_COUNTER_CHECK == 1 ) + // Check if the JoinNonce is greater as the previous one + if( currentJoinNonce > CryptoNvm->JoinNonce ) +#else + // Check if the JoinNonce is different from the previous one + if( currentJoinNonce != CryptoNvm->JoinNonce ) +#endif /* USE_JOIN_NONCE_COUNTER_CHECK */ { - CryptoCtx.NvmCtx->JoinNonce = currentJoinNonce; - CryptoCtx.EventCryptoNvmCtxChanged( ); + CryptoNvm->JoinNonce = currentJoinNonce; } else { return LORAMAC_CRYPTO_FAIL_JOIN_NONCE; } -#endif -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) + // Derive lifetime keys + retval = LoRaMacCryptoDeriveMcRootKey( versionMinor, APP_KEY ); + if( retval != LORAMAC_CRYPTO_SUCCESS ) + { + return retval; + } + + retval = LoRaMacCryptoDeriveMcKEKey( MC_ROOT_KEY ); + if( retval != LORAMAC_CRYPTO_SUCCESS ) + { + return retval; + } + +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) if( versionMinor == 1 ) { // Operating in LoRaWAN 1.1.x mode - // Derive lifetime keys - retval = LoRaMacCryptoDeriveMcRootKey( APP_KEY ); + + retval = DeriveSessionKey11x( F_NWK_S_INT_KEY, currentJoinNonce, joinEUI, nonce ); if( retval != LORAMAC_CRYPTO_SUCCESS ) { return retval; } - retval = LoRaMacCryptoDeriveMcKEKey( MC_ROOT_KEY ); + retval = DeriveSessionKey11x( S_NWK_S_INT_KEY, currentJoinNonce, joinEUI, nonce ); if( retval != LORAMAC_CRYPTO_SUCCESS ) { return retval; } - retval = DeriveSessionKey11x( F_NWK_S_INT_KEY, macMsg->JoinNonce, joinEUI, nonce ); + retval = DeriveSessionKey11x( NWK_S_ENC_KEY, currentJoinNonce, joinEUI, nonce ); if( retval != LORAMAC_CRYPTO_SUCCESS ) { return retval; } - retval = DeriveSessionKey11x( S_NWK_S_INT_KEY, macMsg->JoinNonce, joinEUI, nonce ); + retval = DeriveSessionKey11x( APP_S_KEY, currentJoinNonce, joinEUI, nonce ); if( retval != LORAMAC_CRYPTO_SUCCESS ) { return retval; } + } + else +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ + { + // Operating in LoRaWAN 1.0.x mode + + uint32_t netID; + + netID = ( uint32_t )macMsg->NetID[0]; + netID |= ( ( uint32_t )macMsg->NetID[1] << 8 ); + netID |= ( ( uint32_t )macMsg->NetID[2] << 16 ); - retval = DeriveSessionKey11x( NWK_S_ENC_KEY, macMsg->JoinNonce, joinEUI, nonce ); + retval = DeriveSessionKey10x( APP_S_KEY, currentJoinNonce, netID, nonce ); if( retval != LORAMAC_CRYPTO_SUCCESS ) { return retval; } - retval = DeriveSessionKey11x( APP_S_KEY, macMsg->JoinNonce, joinEUI, nonce ); + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ +#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) + retval = DeriveSessionKey10x( NWK_S_ENC_KEY, currentJoinNonce, netID, nonce ); if( retval != LORAMAC_CRYPTO_SUCCESS ) { return retval; } - } -#else - // Operating in LoRaWAN 1.0.x mode - retval = LoRaMacCryptoDeriveMcRootKey( APP_KEY ); - if( retval != LORAMAC_CRYPTO_SUCCESS ) - { - return retval; - } - retval = LoRaMacCryptoDeriveMcKEKey( MC_ROOT_KEY ); - if( retval != LORAMAC_CRYPTO_SUCCESS ) - { - return retval; - } + retval = DeriveSessionKey10x( F_NWK_S_INT_KEY, currentJoinNonce, netID, nonce ); + if( retval != LORAMAC_CRYPTO_SUCCESS ) + { + return retval; + } - retval = DeriveSessionKey10x( APP_S_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce ); - if( retval != LORAMAC_CRYPTO_SUCCESS ) - { - return retval; - } - retval = DeriveSessionKey10x( NWK_S_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce ); - if( retval != LORAMAC_CRYPTO_SUCCESS ) - { - return retval; - } + retval = DeriveSessionKey10x( S_NWK_S_INT_KEY, currentJoinNonce, netID, nonce ); +#else + retval = DeriveSessionKey10x( NWK_S_KEY, currentJoinNonce, netID, nonce ); #endif /* USE_LRWAN_1_1_X_CRYPTO */ + /* ST_WORKAROUND_END */ + if( retval != LORAMAC_CRYPTO_SUCCESS ) + { + return retval; + } + } // Join-Accept is successfully processed // Save LoRaWAN specification version - CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor = versionMinor; + CryptoNvm->LrWanVersion.Fields.Minor = versionMinor; // Reset frame counters -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - CryptoCtx.RJcount0 = 0; -#endif - CryptoCtx.NvmCtx->FCntList.FCntUp = 0; - CryptoCtx.NvmCtx->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; - - CryptoCtx.EventCryptoNvmCtxChanged( ); +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) + RJcount0 = 0; +#endif /* USE_LRWAN_1_1_X_CRYPTO == 1 */ + CryptoNvm->FCntList.FCntUp = 0; + CryptoNvm->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; return LORAMAC_CRYPTO_SUCCESS; } @@ -1386,7 +1310,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, return LORAMAC_CRYPTO_ERROR_NPE; } - if( fCntUp < CryptoCtx.NvmCtx->FCntList.FCntUp ) + if( fCntUp < CryptoNvm->FCntList.FCntUp ) { return LORAMAC_CRYPTO_FAIL_FCNT_SMALLER; } @@ -1395,14 +1319,16 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, if( macMsg->FPort == 0 ) { // Use network session key + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) payloadDecryptionKeyID = NWK_S_ENC_KEY; #else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ payloadDecryptionKeyID = NWK_S_KEY; #endif /* USE_LRWAN_1_1_X_CRYPTO */ + /* ST_WORKAROUND_END */ } - if( fCntUp > CryptoCtx.NvmCtx->FCntList.FCntUp ) + if( fCntUp > CryptoNvm->FCntList.FCntUp ) { retval = PayloadEncrypt( macMsg->FRMPayload, macMsg->FRMPayloadSize, payloadDecryptionKeyID, macMsg->FHDR.DevAddr, UPLINK, fCntUp ); if( retval != LORAMAC_CRYPTO_SUCCESS ) @@ -1410,8 +1336,8 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, return retval; } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 1 ) { // Encrypt FOpts retval = FOptsEncrypt( macMsg->FHDR.FCtrl.Bits.FOptsLen, macMsg->FHDR.DevAddr, UPLINK, FCNT_UP, fCntUp, macMsg->FHDR.FOpts ); @@ -1420,7 +1346,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, return retval; } } -#endif +#endif /* USE_LRWAN_1_1_X_CRYPTO */ } // Serialize message @@ -1430,8 +1356,8 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, } // Compute mic -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 1 ) { uint32_t cmacS = 0; uint32_t cmacF = 0; @@ -1452,13 +1378,16 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, macMsg->MIC = ( ( cmacF << 16 ) & 0xFFFF0000 ) | ( cmacS & 0x0000FFFF ); } else -#endif - { // Use network session key +#endif /* USE_LRWAN_1_1_X_CRYPTO */ + { + // Use network session key + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) payloadDecryptionKeyID = NWK_S_ENC_KEY; #else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ payloadDecryptionKeyID = NWK_S_KEY; #endif /* USE_LRWAN_1_1_X_CRYPTO */ + /* ST_WORKAROUND_END */ // MIC = cmacF[0..3] // The IsAck parameter is every time false since the ConfFCnt field is not used in legacy mode. retval = ComputeCmacB0( macMsg->Buffer, ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ), payloadDecryptionKeyID, false, UPLINK, macMsg->FHDR.DevAddr, fCntUp, &macMsg->MIC ); @@ -1474,8 +1403,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, return LORAMAC_CRYPTO_ERROR_SERIALIZER; } - CryptoCtx.NvmCtx->FCntList.FCntUp = fCntUp; - CryptoCtx.EventCryptoNvmCtxChanged( ); + CryptoNvm->FCntList.FCntUp = fCntUp; return LORAMAC_CRYPTO_SUCCESS; } @@ -1494,12 +1422,13 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, LoRaMacCryptoStatus_t retval = LORAMAC_CRYPTO_ERROR; KeyIdentifier_t payloadDecryptionKeyID = APP_S_KEY; - + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) KeyIdentifier_t micComputationKeyID = S_NWK_S_INT_KEY; #else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ KeyIdentifier_t micComputationKeyID = NWK_S_KEY; #endif /* USE_LRWAN_1_1_X_CRYPTO */ + /* ST_WORKAROUND_END */ KeyAddr_t* curItem; // Parse the message @@ -1526,7 +1455,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, // Compute mic bool isAck = macMsg->FHDR.FCtrl.Bits.Ack; - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 0 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 0 ) { // In legacy mode the IsAck parameter is forced to be false since the ConfFCnt field is not used. isAck = false; @@ -1543,11 +1472,13 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, if( macMsg->FPort == 0 ) { // Use network session encryption key + /* ST_WORKAROUND_BEGIN: integrate 1.1.x keys only if required */ #if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) payloadDecryptionKeyID = NWK_S_ENC_KEY; #else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ payloadDecryptionKeyID = NWK_S_KEY; #endif /* USE_LRWAN_1_1_X_CRYPTO */ + /* ST_WORKAROUND_END */ } retval = PayloadEncrypt( macMsg->FRMPayload, macMsg->FRMPayloadSize, payloadDecryptionKeyID, address, DOWNLINK, fCntDown ); if( retval != LORAMAC_CRYPTO_SUCCESS ) @@ -1555,8 +1486,8 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, return retval; } -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 ) +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 1 ) { if( addrID == UNICAST_DEV_ADDR ) { @@ -1575,7 +1506,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, return LORAMAC_CRYPTO_SUCCESS; } -LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( KeyIdentifier_t keyID ) +LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( uint8_t versionMinor, KeyIdentifier_t keyID ) { // Prevent other keys than AppKey if( keyID != APP_KEY ) @@ -1584,11 +1515,11 @@ LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( KeyIdentifier_t keyID ) } uint8_t compBase[16] = { 0 }; - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 ) + if( versionMinor == 1 ) { compBase[0] = 0x20; } - if( SecureElementDeriveAndStoreKey( CryptoCtx.NvmCtx->LrWanVersion, compBase, keyID, MC_ROOT_KEY ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementDeriveAndStoreKey( compBase, keyID, MC_ROOT_KEY ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } @@ -1605,7 +1536,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcKEKey( KeyIdentifier_t keyID ) } uint8_t compBase[16] = { 0 }; - if( SecureElementDeriveAndStoreKey( CryptoCtx.NvmCtx->LrWanVersion, compBase, keyID, MC_KE_KEY ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementDeriveAndStoreKey( compBase, keyID, MC_KE_KEY ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } @@ -1648,12 +1579,12 @@ LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcSessionKeyPair( AddressIdentifier_t a compBaseNwkS[3] = ( mcAddr >> 16 ) & 0xFF; compBaseNwkS[4] = ( mcAddr >> 24 ) & 0xFF; - if( SecureElementDeriveAndStoreKey( CryptoCtx.NvmCtx->LrWanVersion, compBaseAppS, curItem->RootKey, curItem->AppSkey ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementDeriveAndStoreKey( compBaseAppS, curItem->RootKey, curItem->AppSkey ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } - if( SecureElementDeriveAndStoreKey( CryptoCtx.NvmCtx->LrWanVersion, compBaseNwkS, curItem->RootKey, curItem->NwkSkey ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementDeriveAndStoreKey( compBaseNwkS, curItem->RootKey, curItem->NwkSkey ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.h index f23bcad1..8f91dbd7 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCrypto.h @@ -48,6 +48,12 @@ extern "C" #include "utilities.h" #include "LoRaMacTypes.h" #include "LoRaMacMessageTypes.h" +#include "LoRaMacCryptoNvm.h" + +/*! + * Indicates if LoRaWAN 1.1.x crypto scheme is enabled + */ +#define USE_LRWAN_1_1_X_CRYPTO 0 /*! * Indicates if a random devnonce must be used or not @@ -163,11 +169,11 @@ typedef void ( *LoRaMacCryptoNvmEvent )( void ); * Initialization of LoRaMac Crypto module * It sets initial values of volatile variables and assigns the non-volatile context. * - * \param[IN] cryptoNvmCtxChanged - Callback function which will be called when the - * non-volatile context have to be stored. + * \param[IN] nvm - Pointer to the non-volatile memory data + * structure. * \retval - Status of the operation */ -LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChanged ); +LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmData_t* nvm ); /*! * Sets the LoRaWAN specification version to be used. @@ -180,22 +186,6 @@ LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChang */ LoRaMacCryptoStatus_t LoRaMacCryptoSetLrWanVersion( Version_t version ); -/*! - * Restores the internal nvm context from passed pointer. - * - * \param[IN] cryptoNmvCtx - Pointer to non-volatile crypto module context to be restored. - * \retval - Status of the operation - */ -LoRaMacCryptoStatus_t LoRaMacCryptoRestoreNvmCtx( void* cryptoNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param[IN] cryptoNvmCtxSize - Size of the module non-volatile context - * \retval - Points to a structure where the module store its non-volatile context - */ -void* LoRaMacCryptoGetNvmCtx( size_t* cryptoNvmCtxSize ); - /*! * Returns updated fCntID downlink counter value. * @@ -303,10 +293,11 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, * 1.1.x * McRootKey = aes128_encrypt(AppKey, 0x20 | pad16) * + * \param[IN] versionMinor - LoRaWAN specification minor version to be used. * \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( AppKey ) * \retval - Status of the operation */ -LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( KeyIdentifier_t keyID ); +LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( uint8_t versionMinor, KeyIdentifier_t keyID ); /*! * Derives the McKEKey from the McRootKey. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCryptoNvm.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCryptoNvm.h new file mode 100644 index 00000000..55869422 --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacCryptoNvm.h @@ -0,0 +1,124 @@ +/*! + * \file LoRaMacCryptoNvm.h + * + * \brief LoRa MAC layer cryptographic NVM data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * addtogroup LORAMAC + * \{ + * + */ +#ifndef __LORAMAC_CRYPTO_NVM_H__ +#define __LORAMAC_CRYPTO_NVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "utilities.h" +#include "LoRaMacTypes.h" + + +/*! + * LoRaWAN Frame counter list. + */ +typedef struct sFCntList +{ + /*! + * Uplink frame counter which is incremented with each uplink. + */ + uint32_t FCntUp; + /*! + * Network downlink frame counter which is incremented with each downlink on FPort 0 + * or when the FPort field is missing. + */ + uint32_t NFCntDown; + /*! + * Application downlink frame counter which is incremented with each downlink + * on a port different than 0. + */ + uint32_t AFCntDown; + /*! + * In case if the device is connected to a LoRaWAN 1.0 Server, + * this counter is used for every kind of downlink frame. + */ + uint32_t FCntDown; + /*! + * Multicast downlink counters + */ + uint32_t McFCntDown[LORAMAC_MAX_MC_CTX]; +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) + /*! + * RJcount1 is a counter incremented with every Rejoin request Type 1 frame transmitted. + */ + uint16_t RJcount1; +#endif +}FCntList_t; + +/*! + * LoRaMac Crypto Non Volatile Context structure + */ +typedef struct sLoRaMacCryptoNvmData +{ + /*! + * Stores the information if the device is connected to a LoRaWAN network + * server with prior to 1.1.0 implementation. + */ + Version_t LrWanVersion; + /*! + * Device nonce is a counter starting at 0 when the device is initially + * powered up and incremented with every JoinRequest. + */ + uint16_t DevNonce; + /*! + * JoinNonce is a device specific counter value (that never repeats itself) + * provided by the join server and incremented with every JoinAccept message. + */ + uint32_t JoinNonce; + /*! + * Frame counter list + */ + FCntList_t FCntList; + /*! + * LastDownFCnt stores the information which frame counter was used to + * decrypt the last frame. This information is needed to compute ConfFCnt in + * B1 block for the MIC. + */ + uint32_t LastDownFCnt; + /*! + * CRC32 value of the Crypto data structure. + */ + uint32_t Crc32; +}LoRaMacCryptoNvmData_t; + +/*! \} addtogroup LORAMAC */ + +#ifdef __cplusplus +} +#endif + +#endif // __LORAMAC_CRYPTO_NVM_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacTypes.h b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacTypes.h index 31f995e9..d5d84cf7 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacTypes.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/LoRaMacTypes.h @@ -32,6 +32,16 @@ * \{ * */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file LoRaMacTypes.h + * @author MCD Application Team + * @brief LoRa MAC layer internal types definition. Please do not include in application sources. + ****************************************************************************** + */ #ifndef __LORAMAC_TYPES_H__ #define __LORAMAC_TYPES_H__ @@ -43,26 +53,525 @@ extern "C" #include #include #include "timer.h" +#include "systime.h" /*! * Start value for unicast keys enumeration */ -#define LORAMAC_CRYPTO_UNICAST_KEYS 0 +#define LORAMAC_CRYPTO_UNICAST_KEYS 0 /*! * Start value for multicast keys enumeration */ -#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 +#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 - /*! - * Indicates if LoRaWAN 1.1.x crypto scheme is enabled +/*! + * Maximum number of multicast context */ -#define USE_LRWAN_1_1_X_CRYPTO 0 +#define LORAMAC_MAX_MC_CTX 1 /* ST_WORKAROUND: reduced LORAMAC_MAX_MC_CTX */ /*! - * Maximum number of multicast context + * Region | SF + * ------------ | :-----: + * AS923 | SF12 - BW125 + * AU915 | SF10 - BW125 + * CN470 | SF12 - BW125 + * CN779 | SF12 - BW125 + * EU433 | SF12 - BW125 + * EU868 | SF12 - BW125 + * IN865 | SF12 - BW125 + * KR920 | SF12 - BW125 + * US915 | SF10 - BW125 + * RU864 | SF12 - BW125 + */ +#define DR_0 0 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF11 - BW125 + * AU915 | SF9 - BW125 + * CN470 | SF11 - BW125 + * CN779 | SF11 - BW125 + * EU433 | SF11 - BW125 + * EU868 | SF11 - BW125 + * IN865 | SF11 - BW125 + * KR920 | SF11 - BW125 + * US915 | SF9 - BW125 + * RU864 | SF11 - BW125 + */ +#define DR_1 1 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF10 - BW125 + * AU915 | SF8 - BW125 + * CN470 | SF10 - BW125 + * CN779 | SF10 - BW125 + * EU433 | SF10 - BW125 + * EU868 | SF10 - BW125 + * IN865 | SF10 - BW125 + * KR920 | SF10 - BW125 + * US915 | SF8 - BW125 + * RU864 | SF10 - BW125 + */ +#define DR_2 2 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF9 - BW125 + * AU915 | SF7 - BW125 + * CN470 | SF9 - BW125 + * CN779 | SF9 - BW125 + * EU433 | SF9 - BW125 + * EU868 | SF9 - BW125 + * IN865 | SF9 - BW125 + * KR920 | SF9 - BW125 + * US915 | SF7 - BW125 + * RU864 | SF9 - BW125 + */ +#define DR_3 3 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF8 - BW125 + * AU915 | SF8 - BW500 + * CN470 | SF8 - BW125 + * CN779 | SF8 - BW125 + * EU433 | SF8 - BW125 + * EU868 | SF8 - BW125 + * IN865 | SF8 - BW125 + * KR920 | SF8 - BW125 + * US915 | SF8 - BW500 + * RU864 | SF8 - BW125 + */ +#define DR_4 4 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF7 - BW125 + * AU915 | RFU + * CN470 | SF7 - BW125 + * CN779 | SF7 - BW125 + * EU433 | SF7 - BW125 + * EU868 | SF7 - BW125 + * IN865 | SF7 - BW125 + * KR920 | SF7 - BW125 + * US915 | RFU + * RU864 | SF7 - BW125 + */ +#define DR_5 5 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF7 - BW250 + * AU915 | RFU + * CN470 | SF12 - BW125 + * CN779 | SF7 - BW250 + * EU433 | SF7 - BW250 + * EU868 | SF7 - BW250 + * IN865 | SF7 - BW250 + * KR920 | RFU + * US915 | RFU + * RU864 | SF7 - BW250 + */ +#define DR_6 6 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | FSK + * AU915 | RFU + * CN470 | SF12 - BW125 + * CN779 | FSK + * EU433 | FSK + * EU868 | FSK + * IN865 | FSK + * KR920 | RFU + * US915 | RFU + * RU864 | FSK + */ +#define DR_7 7 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF12 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF12 - BW500 + * RU864 | RFU + */ +#define DR_8 8 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF11 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF11 - BW500 + * RU864 | RFU + */ +#define DR_9 9 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF10 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF10 - BW500 + * RU864 | RFU + */ +#define DR_10 10 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF9 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF9 - BW500 + * RU864 | RFU + */ +#define DR_11 11 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF8 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF8 - BW500 + * RU864 | RFU + */ +#define DR_12 12 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF7 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF7 - BW500 + * RU864 | RFU + */ +#define DR_13 13 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | RFU + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | RFU + * RU864 | RFU + */ +#define DR_14 14 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | RFU + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | RFU + * RU864 | RFU + */ +#define DR_15 15 + + + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP + * AU915 | Max EIRP + * CN470 | Max EIRP + * CN779 | Max EIRP + * EU433 | Max EIRP + * EU868 | Max EIRP + * IN865 | Max EIRP + * KR920 | Max EIRP + * US915 | Max ERP + * RU864 | Max EIRP + */ +#define TX_POWER_0 0 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 2 + * AU915 | Max EIRP - 2 + * CN470 | Max EIRP - 2 + * CN779 | Max EIRP - 2 + * EU433 | Max EIRP - 2 + * EU868 | Max EIRP - 2 + * IN865 | Max EIRP - 2 + * KR920 | Max EIRP - 2 + * US915 | Max ERP - 2 + * RU864 | Max EIRP - 2 + */ +#define TX_POWER_1 1 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 4 + * AU915 | Max EIRP - 4 + * CN470 | Max EIRP - 4 + * CN779 | Max EIRP - 4 + * EU433 | Max EIRP - 4 + * EU868 | Max EIRP - 4 + * IN865 | Max EIRP - 4 + * KR920 | Max EIRP - 4 + * US915 | Max ERP - 4 + * RU864 | Max EIRP - 4 + */ +#define TX_POWER_2 2 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 6 + * AU915 | Max EIRP - 6 + * CN470 | Max EIRP - 6 + * CN779 | Max EIRP - 6 + * EU433 | Max EIRP - 6 + * EU868 | Max EIRP - 6 + * IN865 | Max EIRP - 6 + * KR920 | Max EIRP - 6 + * US915 | Max ERP - 6 + * RU864 | Max EIRP - 6 + */ +#define TX_POWER_3 3 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 8 + * AU915 | Max EIRP - 8 + * CN470 | Max EIRP - 8 + * CN779 | Max EIRP - 8 + * EU433 | Max EIRP - 8 + * EU868 | Max EIRP - 8 + * IN865 | Max EIRP - 8 + * KR920 | Max EIRP - 8 + * US915 | Max ERP - 8 + * RU864 | Max EIRP - 8 + */ +#define TX_POWER_4 4 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 10 + * AU915 | Max EIRP - 10 + * CN470 | Max EIRP - 10 + * CN779 | Max EIRP - 10 + * EU433 | Max EIRP - 10 + * EU868 | Max EIRP - 10 + * IN865 | Max EIRP - 10 + * KR920 | Max EIRP - 10 + * US915 | Max ERP - 10 + * RU864 | Max EIRP - 10 + */ +#define TX_POWER_5 5 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 12 + * AU915 | Max EIRP - 12 + * CN470 | Max EIRP - 12 + * CN779 | - + * EU433 | - + * EU868 | Max EIRP - 12 + * IN865 | Max EIRP - 12 + * KR920 | Max EIRP - 12 + * US915 | Max ERP - 12 + * RU864 | Max EIRP - 12 + */ +#define TX_POWER_6 6 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 14 + * AU915 | Max EIRP - 14 + * CN470 | Max EIRP - 14 + * CN779 | - + * EU433 | - + * EU868 | Max EIRP - 14 + * IN865 | Max EIRP - 14 + * KR920 | Max EIRP - 14 + * US915 | Max ERP - 14 + * RU864 | Max EIRP - 14 + */ +#define TX_POWER_7 7 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 16 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | Max EIRP - 16 + * KR920 | - + * US915 | Max ERP - 16 + * RU864 | - + */ +#define TX_POWER_8 8 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 18 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | Max EIRP - 18 + * KR920 | - + * US915 | Max ERP - 18 + * RU864 | - */ -#define LORAMAC_MAX_MC_CTX 1 +#define TX_POWER_9 9 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 20 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | Max EIRP - 20 + * KR920 | - + * US915 | Max ERP - 20 + * RU864 | - + */ +#define TX_POWER_10 10 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 22 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 22 + * RU864 | - + */ +#define TX_POWER_11 11 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 24 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 24 + * RU864 | - + */ +#define TX_POWER_12 12 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 26 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 26 + * RU864 | - + */ +#define TX_POWER_13 13 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 28 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 28 + * RU864 | - + */ +#define TX_POWER_14 14 + +/*! + * RFU + */ +#define TX_POWER_15 15 /*! * LoRaWAN devices classes definition @@ -149,24 +658,32 @@ typedef enum eFCntIdentifier * this counter is used for every kind of downlink frame. */ FCNT_DOWN, + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ +#if ( LORAMAC_MAX_MC_CTX > 0 ) /*! * Multicast downlink counter for index 0 */ MC_FCNT_DOWN_0, +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) /*! * Multicast downlink counter for index 1 */ MC_FCNT_DOWN_1, +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) /*! * Multicast downlink counter for index 2 */ MC_FCNT_DOWN_2, +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) /*! * Multicast downlink counter for index 3 */ MC_FCNT_DOWN_3, -#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 3 */ + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ }FCntIdentifier_t; /*! @@ -182,7 +699,7 @@ typedef enum eKeyIdentifier * Network root key */ NWK_KEY, -#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* ST_WORKAROUND: integrate 1.1.x keys only if required */ /*! * Join session integrity key */ @@ -221,6 +738,8 @@ typedef enum eKeyIdentifier * Multicast key encryption key */ MC_KE_KEY = LORAMAC_CRYPTO_MULTICAST_KEYS, + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ +#if ( LORAMAC_MAX_MC_CTX > 0 ) /*! * Multicast root key index 0 */ @@ -233,6 +752,7 @@ typedef enum eKeyIdentifier * Multicast Network session key index 0 */ MC_NWK_S_KEY_0, +#endif /* LORAMAC_MAX_MC_CTX > 0 */ #if ( LORAMAC_MAX_MC_CTX > 1 ) /*! * Multicast root key index 1 @@ -246,6 +766,8 @@ typedef enum eKeyIdentifier * Multicast Network session key index 1 */ MC_NWK_S_KEY_1, +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) /*! * Multicast root key index 2 */ @@ -258,6 +780,8 @@ typedef enum eKeyIdentifier * Multicast Network session key index 2 */ MC_NWK_S_KEY_2, +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) /*! * Multicast root key index 3 */ @@ -270,7 +794,8 @@ typedef enum eKeyIdentifier * Multicast Network session key index 3 */ MC_NWK_S_KEY_3, -#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 3 */ + /* ST_WORKAROUND_END */ /*! * Zero key for slot randomization in class B */ @@ -286,33 +811,36 @@ typedef enum eKeyIdentifier */ typedef enum eAddressIdentifier { + /* ST_WORKAROUND_BEGIN: reduced LORAMAC_MAX_MC_CTX */ +#if ( LORAMAC_MAX_MC_CTX > 0 ) /*! * Multicast Address for index 0 */ MULTICAST_0_ADDR = 0, -#if ( LORAMAC_MAX_MC_CTX == 1 ) - /*! - * Unicast End-device address - */ - UNICAST_DEV_ADDR = 1, -#else /* LORAMAC_MAX_MC_CTX > 1 */ +#endif /* LORAMAC_MAX_MC_CTX > 0 */ +#if ( LORAMAC_MAX_MC_CTX > 1 ) /*! * Multicast Address for index 1 */ - MULTICAST_1_ADDR = 1, + MULTICAST_1_ADDR, +#endif /* LORAMAC_MAX_MC_CTX > 1 */ +#if ( LORAMAC_MAX_MC_CTX > 2 ) /*! * Multicast Address for index 2 */ - MULTICAST_2_ADDR = 2, + MULTICAST_2_ADDR, +#endif /* LORAMAC_MAX_MC_CTX > 2 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) /*! * Multicast Address for index 3 */ - MULTICAST_3_ADDR = 3, + MULTICAST_3_ADDR, +#endif /* LORAMAC_MAX_MC_CTX > 3 */ /*! * Unicast End-device address */ - UNICAST_DEV_ADDR = 4, -#endif /* LORAMAC_MAX_MC_CTX */ + UNICAST_DEV_ADDR, + /* ST_WORKAROUND_END */ }AddressIdentifier_t; /* @@ -624,6 +1152,11 @@ typedef struct sBand * synchronized with the current time */ TimerTime_t LastBandUpdateTime; + /*! + * The last time we have assigned the max + * credits for the 24h interval. + */ + TimerTime_t LastMaxCreditAssignTime; /*! * Current time credits which are available. This * is a value in ms @@ -640,6 +1173,62 @@ typedef struct sBand bool ReadyForTransmission; }Band_t; +/*! + * LoRaMAC channels parameters definition + */ +typedef union uDrRange +{ + /*! + * Byte-access to the bits + */ + int8_t Value; + /*! + * Structure to store the minimum and the maximum datarate + */ + struct sFields + { + /*! + * Minimum data rate + * + * LoRaWAN Regional Parameters V1.0.2rB + * + * The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details. + */ + int8_t Min : 4; + /*! + * Maximum data rate + * + * LoRaWAN Regional Parameters V1.0.2rB + * + * The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details. + */ + int8_t Max : 4; + }Fields; +}DrRange_t; + +/*! + * LoRaMAC channel definition + */ +typedef struct sChannelParams +{ + /*! + * Frequency in Hz + */ + uint32_t Frequency; + /*! + * Alternative frequency for RX window 1 + */ + uint32_t Rx1Frequency; + /*! + * Data rate definition + */ + DrRange_t DrRange; + /*! + * Band index + */ + uint8_t Band; +}ChannelParams_t; + /*! * LoRaMAC frame types * @@ -700,6 +1289,58 @@ typedef enum eLoRaMacBatteryLevel BAT_LEVEL_NO_MEASURE = 0xFF, }LoRaMacBatteryLevel_t; +/*! + * States of the class B beacon acquisition and tracking + */ +typedef enum eBeaconState +{ + /*! + * Initial state to acquire the beacon + */ + BEACON_STATE_ACQUISITION, + /*! + * Beacon acquisition state when a time reference is available + */ + BEACON_STATE_ACQUISITION_BY_TIME, + /*! + * Handles the state when the beacon reception fails + */ + BEACON_STATE_TIMEOUT, + /*! + * Handles the state when the beacon was missed due to an uplink + */ + BEACON_STATE_BEACON_MISSED, + /*! + * Reacquisition state which applies the algorithm to enlarge the reception + * windows + */ + BEACON_STATE_REACQUISITION, + /*! + * The node has locked a beacon successfully + */ + BEACON_STATE_LOCKED, + /*! + * The beacon state machine is stopped due to operations with higher priority + */ + BEACON_STATE_HALT, + /*! + * The node currently operates in the beacon window and is idle. In this + * state, the temperature measurement takes place + */ + BEACON_STATE_IDLE, + /*! + * The node operates in the guard time of class B + */ + BEACON_STATE_GUARD, + /*! + * The node is in receive mode to lock a beacon + */ + BEACON_STATE_RX, + /*! + * The nodes switches the device class + */ + BEACON_STATE_LOST, +}BeaconState_t; #ifdef __cplusplus } #endif diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.c index 727a4694..9076314c 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.c @@ -38,7 +38,6 @@ #define AS923_GET_PHY_PARAM( ) AS923_CASE { return RegionAS923GetPhyParam( getPhy ); } #define AS923_SET_BAND_TX_DONE( ) AS923_CASE { RegionAS923SetBandTxDone( txDone ); break; } #define AS923_INIT_DEFAULTS( ) AS923_CASE { RegionAS923InitDefaults( params ); break; } -#define AS923_GET_NVM_CTX( ) AS923_CASE { return RegionAS923GetNvmCtx( params ); } #define AS923_VERIFY( ) AS923_CASE { return RegionAS923Verify( verify, phyAttribute ); } #define AS923_APPLY_CF_LIST( ) AS923_CASE { RegionAS923ApplyCFList( applyCFList ); break; } #define AS923_CHAN_MASK_SET( ) AS923_CASE { return RegionAS923ChanMaskSet( chanMaskSet ); } @@ -90,7 +89,6 @@ #define AU915_GET_PHY_PARAM( ) AU915_CASE { return RegionAU915GetPhyParam( getPhy ); } #define AU915_SET_BAND_TX_DONE( ) AU915_CASE { RegionAU915SetBandTxDone( txDone ); break; } #define AU915_INIT_DEFAULTS( ) AU915_CASE { RegionAU915InitDefaults( params ); break; } -#define AU915_GET_NVM_CTX( ) AU915_CASE { return RegionAU915GetNvmCtx( params ); } #define AU915_VERIFY( ) AU915_CASE { return RegionAU915Verify( verify, phyAttribute ); } #define AU915_APPLY_CF_LIST( ) AU915_CASE { RegionAU915ApplyCFList( applyCFList ); break; } #define AU915_CHAN_MASK_SET( ) AU915_CASE { return RegionAU915ChanMaskSet( chanMaskSet ); } @@ -142,7 +140,6 @@ #define CN470_GET_PHY_PARAM( ) CN470_CASE { return RegionCN470GetPhyParam( getPhy ); } #define CN470_SET_BAND_TX_DONE( ) CN470_CASE { RegionCN470SetBandTxDone( txDone ); break; } #define CN470_INIT_DEFAULTS( ) CN470_CASE { RegionCN470InitDefaults( params ); break; } -#define CN470_GET_NVM_CTX( ) CN470_CASE { return RegionCN470GetNvmCtx( params ); } #define CN470_VERIFY( ) CN470_CASE { return RegionCN470Verify( verify, phyAttribute ); } #define CN470_APPLY_CF_LIST( ) CN470_CASE { RegionCN470ApplyCFList( applyCFList ); break; } #define CN470_CHAN_MASK_SET( ) CN470_CASE { return RegionCN470ChanMaskSet( chanMaskSet ); } @@ -194,7 +191,6 @@ #define CN779_GET_PHY_PARAM( ) CN779_CASE { return RegionCN779GetPhyParam( getPhy ); } #define CN779_SET_BAND_TX_DONE( ) CN779_CASE { RegionCN779SetBandTxDone( txDone ); break; } #define CN779_INIT_DEFAULTS( ) CN779_CASE { RegionCN779InitDefaults( params ); break; } -#define CN779_GET_NVM_CTX( ) CN779_CASE { return RegionCN779GetNvmCtx( params ); } #define CN779_VERIFY( ) CN779_CASE { return RegionCN779Verify( verify, phyAttribute ); } #define CN779_APPLY_CF_LIST( ) CN779_CASE { RegionCN779ApplyCFList( applyCFList ); break; } #define CN779_CHAN_MASK_SET( ) CN779_CASE { return RegionCN779ChanMaskSet( chanMaskSet ); } @@ -246,7 +242,6 @@ #define EU433_GET_PHY_PARAM( ) EU433_CASE { return RegionEU433GetPhyParam( getPhy ); } #define EU433_SET_BAND_TX_DONE( ) EU433_CASE { RegionEU433SetBandTxDone( txDone ); break; } #define EU433_INIT_DEFAULTS( ) EU433_CASE { RegionEU433InitDefaults( params ); break; } -#define EU433_GET_NVM_CTX( ) EU433_CASE { return RegionEU433GetNvmCtx( params ); } #define EU433_VERIFY( ) EU433_CASE { return RegionEU433Verify( verify, phyAttribute ); } #define EU433_APPLY_CF_LIST( ) EU433_CASE { RegionEU433ApplyCFList( applyCFList ); break; } #define EU433_CHAN_MASK_SET( ) EU433_CASE { return RegionEU433ChanMaskSet( chanMaskSet ); } @@ -298,7 +293,6 @@ #define EU868_GET_PHY_PARAM( ) EU868_CASE { return RegionEU868GetPhyParam( getPhy ); } #define EU868_SET_BAND_TX_DONE( ) EU868_CASE { RegionEU868SetBandTxDone( txDone ); break; } #define EU868_INIT_DEFAULTS( ) EU868_CASE { RegionEU868InitDefaults( params ); break; } -#define EU868_GET_NVM_CTX( ) EU868_CASE { return RegionEU868GetNvmCtx( params ); } #define EU868_VERIFY( ) EU868_CASE { return RegionEU868Verify( verify, phyAttribute ); } #define EU868_APPLY_CF_LIST( ) EU868_CASE { RegionEU868ApplyCFList( applyCFList ); break; } #define EU868_CHAN_MASK_SET( ) EU868_CASE { return RegionEU868ChanMaskSet( chanMaskSet ); } @@ -350,7 +344,6 @@ #define KR920_GET_PHY_PARAM( ) KR920_CASE { return RegionKR920GetPhyParam( getPhy ); } #define KR920_SET_BAND_TX_DONE( ) KR920_CASE { RegionKR920SetBandTxDone( txDone ); break; } #define KR920_INIT_DEFAULTS( ) KR920_CASE { RegionKR920InitDefaults( params ); break; } -#define KR920_GET_NVM_CTX( ) KR920_CASE { return RegionKR920GetNvmCtx( params ); } #define KR920_VERIFY( ) KR920_CASE { return RegionKR920Verify( verify, phyAttribute ); } #define KR920_APPLY_CF_LIST( ) KR920_CASE { RegionKR920ApplyCFList( applyCFList ); break; } #define KR920_CHAN_MASK_SET( ) KR920_CASE { return RegionKR920ChanMaskSet( chanMaskSet ); } @@ -402,7 +395,6 @@ #define IN865_GET_PHY_PARAM( ) IN865_CASE { return RegionIN865GetPhyParam( getPhy ); } #define IN865_SET_BAND_TX_DONE( ) IN865_CASE { RegionIN865SetBandTxDone( txDone ); break; } #define IN865_INIT_DEFAULTS( ) IN865_CASE { RegionIN865InitDefaults( params ); break; } -#define IN865_GET_NVM_CTX( ) IN865_CASE { return RegionIN865GetNvmCtx( params ); } #define IN865_VERIFY( ) IN865_CASE { return RegionIN865Verify( verify, phyAttribute ); } #define IN865_APPLY_CF_LIST( ) IN865_CASE { RegionIN865ApplyCFList( applyCFList ); break; } #define IN865_CHAN_MASK_SET( ) IN865_CASE { return RegionIN865ChanMaskSet( chanMaskSet ); } @@ -454,7 +446,6 @@ #define US915_GET_PHY_PARAM( ) US915_CASE { return RegionUS915GetPhyParam( getPhy ); } #define US915_SET_BAND_TX_DONE( ) US915_CASE { RegionUS915SetBandTxDone( txDone ); break; } #define US915_INIT_DEFAULTS( ) US915_CASE { RegionUS915InitDefaults( params ); break; } -#define US915_GET_NVM_CTX( ) US915_CASE { return RegionUS915GetNvmCtx( params ); } #define US915_VERIFY( ) US915_CASE { return RegionUS915Verify( verify, phyAttribute ); } #define US915_APPLY_CF_LIST( ) US915_CASE { RegionUS915ApplyCFList( applyCFList ); break; } #define US915_CHAN_MASK_SET( ) US915_CASE { return RegionUS915ChanMaskSet( chanMaskSet ); } @@ -506,7 +497,6 @@ #define RU864_GET_PHY_PARAM( ) RU864_CASE { return RegionRU864GetPhyParam( getPhy ); } #define RU864_SET_BAND_TX_DONE( ) RU864_CASE { RegionRU864SetBandTxDone( txDone ); break; } #define RU864_INIT_DEFAULTS( ) RU864_CASE { RegionRU864InitDefaults( params ); break; } -#define RU864_GET_NVM_CTX( ) RU864_CASE { return RegionRU864GetNvmCtx( params ); } #define RU864_VERIFY( ) RU864_CASE { return RegionRU864Verify( verify, phyAttribute ); } #define RU864_APPLY_CF_LIST( ) RU864_CASE { RegionRU864ApplyCFList( applyCFList ); break; } #define RU864_CHAN_MASK_SET( ) RU864_CASE { return RegionRU864ChanMaskSet( chanMaskSet ); } @@ -636,27 +626,6 @@ void RegionInitDefaults( LoRaMacRegion_t region, InitDefaultsParams_t* params ) } } -void* RegionGetNvmCtx( LoRaMacRegion_t region, GetNvmCtxParams_t* params ) -{ - switch( region ) - { - AS923_GET_NVM_CTX( ); - AU915_GET_NVM_CTX( ); - CN470_GET_NVM_CTX( ); - CN779_GET_NVM_CTX( ); - EU433_GET_NVM_CTX( ); - EU868_GET_NVM_CTX( ); - KR920_GET_NVM_CTX( ); - IN865_GET_NVM_CTX( ); - US915_GET_NVM_CTX( ); - RU864_GET_NVM_CTX( ); - default: - { - return 0; - } - } -} - bool RegionVerify( LoRaMacRegion_t region, VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( region ) @@ -825,7 +794,7 @@ uint8_t RegionRxParamSetupReq( LoRaMacRegion_t region, RxParamSetupReqParams_t* } } -uint8_t RegionNewChannelReq( LoRaMacRegion_t region, NewChannelReqParams_t* newChannelReq ) +int8_t RegionNewChannelReq( LoRaMacRegion_t region, NewChannelReqParams_t* newChannelReq ) { switch( region ) { @@ -867,7 +836,7 @@ int8_t RegionTxParamSetupReq( LoRaMacRegion_t region, TxParamSetupReqParams_t* t } } -uint8_t RegionDlChannelReq( LoRaMacRegion_t region, DlChannelReqParams_t* dlChannelReq ) +int8_t RegionDlChannelReq( LoRaMacRegion_t region, DlChannelReqParams_t* dlChannelReq ) { switch( region ) { diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.h index cc63dd0b..47894aaf 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/Region.h @@ -78,511 +78,6 @@ extern "C" -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF12 - BW125 - * AU915 | SF10 - BW125 - * CN470 | SF12 - BW125 - * CN779 | SF12 - BW125 - * EU433 | SF12 - BW125 - * EU868 | SF12 - BW125 - * IN865 | SF12 - BW125 - * KR920 | SF12 - BW125 - * US915 | SF10 - BW125 - * RU864 | SF12 - BW125 - */ -#define DR_0 0 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF11 - BW125 - * AU915 | SF9 - BW125 - * CN470 | SF11 - BW125 - * CN779 | SF11 - BW125 - * EU433 | SF11 - BW125 - * EU868 | SF11 - BW125 - * IN865 | SF11 - BW125 - * KR920 | SF11 - BW125 - * US915 | SF9 - BW125 - * RU864 | SF11 - BW125 - */ -#define DR_1 1 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF10 - BW125 - * AU915 | SF8 - BW125 - * CN470 | SF10 - BW125 - * CN779 | SF10 - BW125 - * EU433 | SF10 - BW125 - * EU868 | SF10 - BW125 - * IN865 | SF10 - BW125 - * KR920 | SF10 - BW125 - * US915 | SF8 - BW125 - * RU864 | SF10 - BW125 - */ -#define DR_2 2 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF9 - BW125 - * AU915 | SF7 - BW125 - * CN470 | SF9 - BW125 - * CN779 | SF9 - BW125 - * EU433 | SF9 - BW125 - * EU868 | SF9 - BW125 - * IN865 | SF9 - BW125 - * KR920 | SF9 - BW125 - * US915 | SF7 - BW125 - * RU864 | SF9 - BW125 - */ -#define DR_3 3 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF8 - BW125 - * AU915 | SF8 - BW500 - * CN470 | SF8 - BW125 - * CN779 | SF8 - BW125 - * EU433 | SF8 - BW125 - * EU868 | SF8 - BW125 - * IN865 | SF8 - BW125 - * KR920 | SF8 - BW125 - * US915 | SF8 - BW500 - * RU864 | SF8 - BW125 - */ -#define DR_4 4 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF7 - BW125 - * AU915 | RFU - * CN470 | SF7 - BW125 - * CN779 | SF7 - BW125 - * EU433 | SF7 - BW125 - * EU868 | SF7 - BW125 - * IN865 | SF7 - BW125 - * KR920 | SF7 - BW125 - * US915 | RFU - * RU864 | SF7 - BW125 - */ -#define DR_5 5 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF7 - BW250 - * AU915 | RFU - * CN470 | SF12 - BW125 - * CN779 | SF7 - BW250 - * EU433 | SF7 - BW250 - * EU868 | SF7 - BW250 - * IN865 | SF7 - BW250 - * KR920 | RFU - * US915 | RFU - * RU864 | SF7 - BW250 - */ -#define DR_6 6 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | FSK - * AU915 | RFU - * CN470 | SF12 - BW125 - * CN779 | FSK - * EU433 | FSK - * EU868 | FSK - * IN865 | FSK - * KR920 | RFU - * US915 | RFU - * RU864 | FSK - */ -#define DR_7 7 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF12 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF12 - BW500 - * RU864 | RFU - */ -#define DR_8 8 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF11 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF11 - BW500 - * RU864 | RFU - */ -#define DR_9 9 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF10 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF10 - BW500 - * RU864 | RFU - */ -#define DR_10 10 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF9 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF9 - BW500 - * RU864 | RFU - */ -#define DR_11 11 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF8 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF8 - BW500 - * RU864 | RFU - */ -#define DR_12 12 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF7 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF7 - BW500 - * RU864 | RFU - */ -#define DR_13 13 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | RFU - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | RFU - * RU864 | RFU - */ -#define DR_14 14 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | RFU - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | RFU - * RU864 | RFU - */ -#define DR_15 15 - - - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - * AU915 | Max EIRP - * CN470 | Max EIRP - * CN779 | Max EIRP - * EU433 | Max EIRP - * EU868 | Max EIRP - * IN865 | Max EIRP - * KR920 | Max EIRP - * US915 | Max ERP - * RU864 | Max EIRP - */ -#define TX_POWER_0 0 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 2 - * AU915 | Max EIRP - 2 - * CN470 | Max EIRP - 2 - * CN779 | Max EIRP - 2 - * EU433 | Max EIRP - 2 - * EU868 | Max EIRP - 2 - * IN865 | Max EIRP - 2 - * KR920 | Max EIRP - 2 - * US915 | Max ERP - 2 - * RU864 | Max EIRP - 2 - */ -#define TX_POWER_1 1 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 4 - * AU915 | Max EIRP - 4 - * CN470 | Max EIRP - 4 - * CN779 | Max EIRP - 4 - * EU433 | Max EIRP - 4 - * EU868 | Max EIRP - 4 - * IN865 | Max EIRP - 4 - * KR920 | Max EIRP - 4 - * US915 | Max ERP - 4 - * RU864 | Max EIRP - 4 - */ -#define TX_POWER_2 2 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 6 - * AU915 | Max EIRP - 6 - * CN470 | Max EIRP - 6 - * CN779 | Max EIRP - 6 - * EU433 | Max EIRP - 6 - * EU868 | Max EIRP - 6 - * IN865 | Max EIRP - 6 - * KR920 | Max EIRP - 6 - * US915 | Max ERP - 6 - * RU864 | Max EIRP - 6 - */ -#define TX_POWER_3 3 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 8 - * AU915 | Max EIRP - 8 - * CN470 | Max EIRP - 8 - * CN779 | Max EIRP - 8 - * EU433 | Max EIRP - 8 - * EU868 | Max EIRP - 8 - * IN865 | Max EIRP - 8 - * KR920 | Max EIRP - 8 - * US915 | Max ERP - 8 - * RU864 | Max EIRP - 8 - */ -#define TX_POWER_4 4 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 10 - * AU915 | Max EIRP - 10 - * CN470 | Max EIRP - 10 - * CN779 | Max EIRP - 10 - * EU433 | Max EIRP - 10 - * EU868 | Max EIRP - 10 - * IN865 | Max EIRP - 10 - * KR920 | Max EIRP - 10 - * US915 | Max ERP - 10 - * RU864 | Max EIRP - 10 - */ -#define TX_POWER_5 5 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 12 - * AU915 | Max EIRP - 12 - * CN470 | Max EIRP - 12 - * CN779 | - - * EU433 | - - * EU868 | Max EIRP - 12 - * IN865 | Max EIRP - 12 - * KR920 | Max EIRP - 12 - * US915 | Max ERP - 12 - * RU864 | Max EIRP - 12 - */ -#define TX_POWER_6 6 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 14 - * AU915 | Max EIRP - 14 - * CN470 | Max EIRP - 14 - * CN779 | - - * EU433 | - - * EU868 | Max EIRP - 14 - * IN865 | Max EIRP - 14 - * KR920 | Max EIRP - 14 - * US915 | Max ERP - 14 - * RU864 | Max EIRP - 14 - */ -#define TX_POWER_7 7 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 16 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | Max EIRP - 16 - * KR920 | - - * US915 | Max ERP - 16 - * RU864 | - - */ -#define TX_POWER_8 8 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 18 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | Max EIRP - 18 - * KR920 | - - * US915 | Max ERP - 18 - * RU864 | - - */ -#define TX_POWER_9 9 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 20 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | Max EIRP - 20 - * KR920 | - - * US915 | Max ERP - 20 - * RU864 | - - */ -#define TX_POWER_10 10 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 22 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 22 - * RU864 | - - */ -#define TX_POWER_11 11 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 24 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 24 - * RU864 | - - */ -#define TX_POWER_12 12 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 26 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 26 - * RU864 | - - */ -#define TX_POWER_13 13 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 28 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 28 - * RU864 | - - */ -#define TX_POWER_14 14 - -/*! - * RFU - */ -#define TX_POWER_15 15 - - - /*! * Enumeration of phy attributes. */ @@ -649,10 +144,12 @@ typedef enum ePhyAttribute * Maximum payload possible. */ PHY_MAX_PAYLOAD, + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload possible when repeater support is enabled. */ PHY_MAX_PAYLOAD_REPEATER, + /* ST_WORKAROUND_END */ /*! * Duty cycle. */ @@ -799,14 +296,14 @@ typedef enum ePhyAttribute * The beacon channel datarate. */ PHY_BEACON_CHANNEL_DR, - /*! - * The frequency stepwidth between the beacon channels. - */ - PHY_BEACON_CHANNEL_STEPWIDTH, /*! * The number of channels for the beacon reception. */ PHY_BEACON_NB_CHANNELS, + /*! + * The static offset for the downlink channel calculation. + */ + PHY_BEACON_CHANNEL_OFFSET, /*! * Ping slot channel frequency. */ @@ -815,7 +312,7 @@ typedef enum ePhyAttribute * The datarate of a ping slot channel. */ PHY_PING_SLOT_CHANNEL_DR, - /* + /*! * The number of channels for the ping slot reception. */ PHY_PING_SLOT_NB_CHANNELS, @@ -850,11 +347,7 @@ typedef enum eInitType * Activates the default channels. Leaves all other active channels * active. */ - INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS, - /*! - * Restores internal context from passed pointer. - */ - INIT_TYPE_RESTORE_CTX + INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS }InitType_t; typedef enum eChannelsMask @@ -989,26 +482,18 @@ typedef struct sSetBandTxDoneParams typedef struct sInitDefaultsParams { /*! - * Pointer to region module context to be restored. + * Pointer to region NVM group1. */ - void* NvmCtx; + void* NvmGroup1; /*! - * Sets the initialization type. + * Pointer to region NVM group2. */ - InitType_t Type; -}InitDefaultsParams_t; - -/*! - * Parameter structure for the function RegionGetNvmCtx. - */ -typedef struct sGetNvmCtxParams -{ + void* NvmGroup2; /*! - * Size of module context. + * Sets the initialization type. */ - size_t nvmCtxSize; -}GetNvmCtxParams_t; - + InitType_t Type; +}InitDefaultsParams_t; /*! * Parameter structure for the function RegionVerify. @@ -1114,10 +599,12 @@ typedef struct sRxConfigParams * Downlink dwell time. */ uint8_t DownlinkDwellTime; + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Set to true, if a repeater is supported. */ bool RepeaterSupport; + /* ST_WORKAROUND_END */ /*! * Set to true, if RX should be continuous. */ @@ -1437,17 +924,6 @@ void RegionSetBandTxDone( LoRaMacRegion_t region, SetBandTxDoneParams_t* txDone */ void RegionInitDefaults( LoRaMacRegion_t region, InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [IN] region LoRaWAN region. - * - * \param [IN] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionGetNvmCtx( LoRaMacRegion_t region, GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -1604,7 +1080,7 @@ uint8_t RegionRxParamSetupReq( LoRaMacRegion_t region, RxParamSetupReqParams_t* * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionNewChannelReq( LoRaMacRegion_t region, NewChannelReqParams_t* newChannelReq ); +int8_t RegionNewChannelReq( LoRaMacRegion_t region, NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -1628,7 +1104,7 @@ int8_t RegionTxParamSetupReq( LoRaMacRegion_t region, TxParamSetupReqParams_t* t * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionDlChannelReq( LoRaMacRegion_t region, DlChannelReqParams_t* dlChannelReq ); +int8_t RegionDlChannelReq( LoRaMacRegion_t region, DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.c index 39da9b49..3438c2c6 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.c @@ -28,10 +28,20 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionAS923.c + * @author MCD Application Team + * @brief Region implementation for AS923 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionAS923.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 1 @@ -71,6 +81,8 @@ // Channel plan CHANNEL_PLAN_GROUP_AS923_1_JP +#define REGION_AS923_FREQ_OFFSET 0 + /*! * Restrict AS923 frequencies to channels 24 to 38 * Center frequencies 920.6 MHz to 923.4 MHz @ 200 kHz max bandwidth @@ -91,84 +103,24 @@ #define AS923_RX_MAX_DATARATE DR_5 #undef AS923_DEFAULT_UPLINK_DWELL_TIME -#define AS923_DEFAULT_UPLINK_DWELL_TIME DR_5 +#define AS923_DEFAULT_UPLINK_DWELL_TIME 0 #undef AS923_DEFAULT_DOWNLINK_DWELL_TIME -#define AS923_DEFAULT_DOWNLINK_DWELL_TIME DR_5 +#define AS923_DEFAULT_DOWNLINK_DWELL_TIME 0 #undef AS923_DEFAULT_MAX_EIRP #define AS923_DEFAULT_MAX_EIRP 13.0f #endif /* REGION_AS923_DEFAULT_CHANNEL_PLAN */ -/*! - * Region specific context - */ -typedef struct sRegionAS923NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ AS923_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ AS923_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionAS923NvmCtx_t; - +#if defined( REGION_AS923 ) /* * Non-volatile module context. */ -static RegionAS923NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsAS923[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - static bool VerifyRfFreq( uint32_t freq ) { // Check radio driver support @@ -187,7 +139,7 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesAS923[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsAS923 ); TimerTime_t timeOnAir = 0; if( datarate == DR_7 ) @@ -200,11 +152,13 @@ static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) } return timeOnAir; } +#endif /* REGION_AS923 */ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_AS923 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -238,14 +192,16 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - if( getPhy->UplinkDwellTime == 0 ) + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, AS923_TX_MIN_DATARATE ); - } - else - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, AS923_DWELL_LIMIT_DATARATE ); - } + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )AS923_TX_MAX_DATARATE, + .MinDr = ( int8_t )( ( getPhy->UplinkDwellTime == 0 ) ? AS923_TX_MIN_DATARATE : AS923_DWELL_LIMIT_DATARATE ), + .NbChannels = AS923_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -260,12 +216,12 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = AS923_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = AS923_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -276,10 +232,11 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } else { - phyParam.Value = MaxPayloadOfDatarateDwell1UpAS923[getPhy->Datarate]; + phyParam.Value = MaxPayloadOfDatarateDwell1AS923[getPhy->Datarate]; } break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { if( getPhy->UplinkDwellTime == 0 ) @@ -288,10 +245,11 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } else { - phyParam.Value = MaxPayloadOfDatarateDwell1UpAS923[getPhy->Datarate]; + phyParam.Value = MaxPayloadOfDatarateDwell1AS923[getPhy->Datarate]; } break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = AS923_DUTY_CYCLE_ENABLED; @@ -304,42 +262,42 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = AS923_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = AS923_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = AS923_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = AS923_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = AS923_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( AS923_ACKTIMEOUT + randr( -AS923_ACK_TIMEOUT_RND, AS923_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = AS923_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: { - phyParam.Value = AS923_RX_WND_2_FREQ; + phyParam.Value = AS923_RX_WND_2_FREQ - REGION_AS923_FREQ_OFFSET; break; } case PHY_DEF_RX2_DR: @@ -349,12 +307,12 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -364,7 +322,7 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -389,7 +347,7 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BEACON_CHANNEL_FREQ: { - phyParam.Value = AS923_BEACON_CHANNEL_FREQ; + phyParam.Value = AS923_BEACON_CHANNEL_FREQ - REGION_AS923_FREQ_OFFSET; break; } case PHY_BEACON_FORMAT: @@ -421,7 +379,7 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsAS923 ); break; } default: @@ -430,17 +388,21 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_AS923 */ return phyParam; } void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_AS923 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_AS923 */ } void RegionAS923InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_AS923 ) Band_t bands[AS923_MAX_NB_BANDS] = { AS923_BAND0 @@ -450,41 +412,45 @@ void RegionAS923InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * AS923_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * AS923_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) AS923_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) AS923_LC2; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) AS923_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) AS923_LC2; + + // Apply frequency offset + RegionNvmGroup2->Channels[0].Frequency -= REGION_AS923_FREQ_OFFSET; + RegionNvmGroup2->Channels[1].Frequency -= REGION_AS923_FREQ_OFFSET; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Activate channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -492,16 +458,12 @@ void RegionAS923InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionAS923GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionAS923NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_AS923 */ } bool RegionAS923Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_AS923 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -547,10 +509,14 @@ bool RegionAS923Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_AS923 */ } void RegionAS923ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_AS923 ) ChannelParams_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; @@ -606,52 +572,58 @@ void RegionAS923ApplyCFList( ApplyCFListParams_t* applyCFList ) RegionAS923ChannelsRemove( &channelRemove ); } } +#endif /* REGION_AS923 */ } bool RegionAS923ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_AS923 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_AS923 */ } void RegionAS923ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_AS923 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, AS923_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsAS923 ); if( rxConfigParams->Datarate == DR_7 ) { // FSK - tSymbol = RegionCommonComputeSymbolTimeFsk( DataratesAS923[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeFsk( DataratesAS923[rxConfigParams->Datarate] ); } else { // LoRa - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesAS923[rxConfigParams->Datarate], BandwidthsAS923[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesAS923[rxConfigParams->Datarate], BandwidthsAS923[rxConfigParams->Datarate] ); } - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_AS923 */ } bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_AS923 ) RadioModems_t modem; int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; @@ -666,11 +638,11 @@ bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -691,7 +663,7 @@ bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); } - // Check for repeater support + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterDwell0AS923[dr]; @@ -702,27 +674,33 @@ bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) } Radio.SetMaxPayloadLength( modem, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_AS923 */ } bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_AS923 ) RadioModems_t modem; int8_t phyDr = DataratesAS923[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsAS923 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -735,7 +713,7 @@ bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); } /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Update time-on-air @@ -746,11 +724,15 @@ bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_AS923 */ } uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_AS923 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -793,7 +775,7 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -801,7 +783,7 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -827,7 +809,7 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = AS923_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = AS923_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = AS923_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -839,9 +821,9 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -850,12 +832,14 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_AS923 */ return status; } uint8_t RegionAS923RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_AS923 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -875,10 +859,11 @@ uint8_t RegionAS923RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_AS923 */ return status; } -uint8_t RegionAS923NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionAS923NewChannelReq( NewChannelReqParams_t* newChannelReq ) { uint8_t status = 0x03; ChannelAddParams_t channelAdd; @@ -937,10 +922,11 @@ int8_t RegionAS923TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) return 0; } -uint8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { uint8_t status = 0x03; +#if defined( REGION_AS923 ) // Verify if the frequency is supported if( VerifyRfFreq( dlChannelReq->Rx1Frequency ) == false ) { @@ -948,7 +934,7 @@ uint8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -956,40 +942,47 @@ uint8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } +#endif /* REGION_AS923 */ return status; } int8_t RegionAS923AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_AS923 ) // Only AS923_DWELL_LIMIT_DATARATE is supported return AS923_DWELL_LIMIT_DATARATE; +#else + return -1; +#endif /* REGION_AS923 */ } LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_AS923 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[AS923_MAX_NB_CHANNELS] = { 0 }; RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; + uint16_t joinChannels = AS923_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = AS923_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = AS923_JOIN_CHANNELS; + countChannelsParams.JoinChannels = &joinChannels; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -1018,7 +1011,7 @@ LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_ // Perform carrier sense for AS923_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism - if( Radio.IsChannelFree( NvmCtx.Channels[channelNext].Frequency, AS923_LBT_RX_BANDWIDTH, AS923_RSSI_FREE_TH, AS923_CARRIER_SENSE_TIME ) == true ) + if( Radio.IsChannelFree( RegionNvmGroup2->Channels[channelNext].Frequency, AS923_LBT_RX_BANDWIDTH, AS923_RSSI_FREE_TH, AS923_CARRIER_SENSE_TIME ) == true ) { // Free channel found *channel = channelNext; @@ -1036,13 +1029,17 @@ LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_AS923 */ } LoRaMacStatus_t RegionAS923ChannelAdd( ChannelAddParams_t* channelAdd ) { +#if defined( REGION_AS923 ) bool drInvalid = false; bool freqInvalid = false; uint8_t id = channelAdd->ChannelId; @@ -1094,14 +1091,18 @@ LoRaMacStatus_t RegionAS923ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_AS923 */ } bool RegionAS923ChannelsRemove( ChannelRemoveParams_t* channelRemove ) { +#if defined( REGION_AS923 ) uint8_t id = channelRemove->ChannelId; if( id < AS923_NUMB_DEFAULT_CHANNELS ) @@ -1110,25 +1111,31 @@ bool RegionAS923ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, AS923_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, AS923_MAX_NB_CHANNELS ); +#else + return false; +#endif /* REGION_AS923 */ } void RegionAS923SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_AS923 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_AS923 */ } uint8_t RegionAS923ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_AS923 ) // Initialize minDr for a downlink dwell time configuration of 0 int8_t minDr = DR_0; @@ -1140,10 +1147,15 @@ uint8_t RegionAS923ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d // Apply offset formula return MIN( DR_5, MAX( minDr, dr - EffectiveRx1DrOffsetAS923[drOffset] ) ); +#else + return 0; +#endif /* REGION_AS923 */ + } void RegionAS923RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_AS923 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesAS923; @@ -1158,4 +1170,5 @@ void RegionAS923RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = AS923_BEACON_CHANNEL_DR; +#endif /* REGION_AS923 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.h index 9270d9ed..8edd214a 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAS923.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionAS923.h + * @author MCD Application Team + * @brief Region definition for AS923 + ****************************************************************************** + */ #ifndef __REGION_AS923_H__ #define __REGION_AS923_H__ @@ -124,11 +134,6 @@ extern "C" */ #define AS923_MAX_RX1_DR_OFFSET 7 -/*! - * Default Rx1 receive datarate offset - */ -#define AS923_DEFAULT_RX1_DR_OFFSET 0 - /*! * Minimal Tx output power that can be used by the node */ @@ -164,16 +169,6 @@ extern "C" */ #define AS923_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define AS923_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define AS923_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -184,41 +179,6 @@ extern "C" */ #define AS923_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define AS923_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define AS923_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define AS923_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define AS923_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define AS923_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define AS923_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define AS923_ACK_TIMEOUT_RND 1000 - #if ( AS923_DEFAULT_DATARATE > DR_5 ) #error "A default DR higher than DR_5 may lead to connectivity loss." #endif @@ -283,9 +243,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 % +#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -324,6 +284,7 @@ static const uint8_t DataratesAS923[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; */ static const uint32_t BandwidthsAS923[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. * The table is valid for the dwell time configuration of 0 for uplinks and downlinks. @@ -339,15 +300,10 @@ static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AS923[] = { 51, 51, 51, 1 /*! * Maximum payload with respect to the datarate index. Can operate with and without repeater. - * The table proides repeater support. The table is only valid for uplinks. + * The table provides repeater support. The table is for uplinks and downlinks. */ -static const uint8_t MaxPayloadOfDatarateDwell1UpAS923[] = { 0, 0, 11, 53, 125, 242, 242, 242 }; - -/*! - * Maximum payload with respect to the datarate index. Can operate with and without repeater. - * The table proides repeater support. The table is only valid for downlinks. - */ -static const uint8_t MaxPayloadOfDatarateDwell1DownAS923[] = { 0, 0, 11, 53, 126, 242, 242, 242 }; +static const uint8_t MaxPayloadOfDatarateDwell1AS923[] = { 0, 0, 11, 53, 125, 242, 242, 242 }; +/* ST_WORKAROUND_END */ /*! * Effective datarate offsets for receive window 1. @@ -377,15 +333,6 @@ void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionAS923InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionAS923GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -478,7 +425,7 @@ uint8_t RegionAS923RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionAS923NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionAS923NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -498,7 +445,7 @@ int8_t RegionAS923TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.c index 13a3aa0f..e71fbbb5 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.c @@ -28,10 +28,21 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionAU915.c + * @author MCD Application Team + * @brief Region implementation for AU915 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionAU915.h" +#include "RegionBaseUS.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 6 @@ -39,81 +50,12 @@ // A mask to select only valid 500KHz channels #define CHANNELS_MASK_500KHZ_MASK 0x00FF -/*! - * Region specific context - */ -typedef struct sRegionAU915NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ AU915_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ AU915_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels remaining - */ - uint16_t ChannelsMaskRemaining[CHANNELS_MASK_SIZE]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionAU915NvmCtx_t; - +#if defined( REGION_AU915 ) /* * Non-volatile module context. */ -static RegionAU915NvmCtx_t NvmCtx; - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else if( dr == DR_8 ) - { // DR_7 is not allowed - nextLowerDr = DR_6; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsAU915[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; static bool VerifyRfFreq( uint32_t freq ) { @@ -131,8 +73,7 @@ static bool VerifyRfFreq( uint32_t freq ) return false; } - // Tx frequencies for 125kHz - // Also includes the range for 500kHz channels + // Test for frequency range - take RX and TX frequencies into account if( ( freq < 915200000 ) || ( freq > 927800000 ) ) { return false; @@ -143,15 +84,17 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesAU915[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsAU915 ); return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true ); } +#endif /* REGION_AU915 */ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_AU915 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -185,14 +128,16 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - if( getPhy->UplinkDwellTime == 0) - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, AU915_TX_MIN_DATARATE ); - } - else + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, AU915_DWELL_LIMIT_DATARATE ); - } + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )AU915_TX_MAX_DATARATE, + .MinDr = ( int8_t )( ( getPhy->UplinkDwellTime == 0 ) ? AU915_TX_MIN_DATARATE : AU915_DWELL_LIMIT_DATARATE ), + .NbChannels = AU915_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -207,12 +152,12 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = AU915_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = AU915_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -227,6 +172,7 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { if( getPhy->UplinkDwellTime == 0) @@ -239,6 +185,7 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = AU915_DUTY_CYCLE_ENABLED; @@ -251,37 +198,37 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = AU915_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = AU915_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = AU915_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = AU915_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = AU915_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( AU915_ACKTIMEOUT + randr( -AU915_ACK_TIMEOUT_RND, AU915_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = AU915_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -296,12 +243,12 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -311,7 +258,7 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -321,7 +268,7 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = AU915_DEFAULT_DOWNLINK_DWELL_TIME; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -336,7 +283,9 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BEACON_CHANNEL_FREQ: { - phyParam.Value = AU915_BEACON_CHANNEL_FREQ + ( getPhy->Channel * AU915_BEACON_CHANNEL_STEPWIDTH ); + phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel, + AU915_BEACON_CHANNEL_FREQ, + AU915_BEACON_CHANNEL_STEPWIDTH ); break; } case PHY_BEACON_FORMAT: @@ -351,24 +300,16 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = AU915_BEACON_CHANNEL_DR; break; } - case PHY_BEACON_CHANNEL_STEPWIDTH: - { - phyParam.Value = AU915_BEACON_CHANNEL_STEPWIDTH; - break; - } case PHY_BEACON_NB_CHANNELS: { phyParam.Value = AU915_BEACON_NB_CHANNELS; break; } - case PHY_PING_SLOT_NB_CHANNELS: - { - phyParam.Value = AU915_PING_SLOT_NB_CHANNELS; - break; - } case PHY_PING_SLOT_CHANNEL_FREQ: { - phyParam.Value = AU915_PING_SLOT_CHANNEL_FREQ + ( getPhy->Channel * AU915_BEACON_CHANNEL_STEPWIDTH ); + phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel, + AU915_PING_SLOT_CHANNEL_FREQ, + AU915_BEACON_CHANNEL_STEPWIDTH ); break; } case PHY_PING_SLOT_CHANNEL_DR: @@ -376,6 +317,11 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = AU915_PING_SLOT_CHANNEL_DR; break; } + case PHY_PING_SLOT_NB_CHANNELS: + { + phyParam.Value = AU915_BEACON_NB_CHANNELS; + break; + } case PHY_SF_FROM_DR: { phyParam.Value = DataratesAU915[getPhy->Datarate]; @@ -383,7 +329,7 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsAU915 ); break; } default: @@ -392,17 +338,21 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_AU915 */ return phyParam; } void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_AU915 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_AU915 */ } void RegionAU915InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_AU915 ) Band_t bands[AU915_MAX_NB_BANDS] = { AU915_BAND0 @@ -412,49 +362,63 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + + // Initialize 8 bit channel groups index + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; + + // Initialize the join trials counter + RegionNvmGroup1->JoinTrialsCounter = 0; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS ); // Channels for( uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++ ) { // 125 kHz channels - NvmCtx.Channels[i].Frequency = 915200000 + i * 200000; - NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 915200000 + i * 200000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; + RegionNvmGroup2->Channels[i].Band = 0; } for( uint8_t i = AU915_MAX_NB_CHANNELS - 8; i < AU915_MAX_NB_CHANNELS; i++ ) { // 500 kHz channels - NvmCtx.Channels[i].Frequency = 915900000 + ( i - ( AU915_MAX_NB_CHANNELS - 8 ) ) * 1600000; - NvmCtx.Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 915900000 + ( i - ( AU915_MAX_NB_CHANNELS - 8 ) ) * 1600000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6; + RegionNvmGroup2->Channels[i].Band = 0; } // Initialize channels default mask /* ST_WORKAROUND_BEGIN: Hybrid mode */ #if ( HYBRID_ENABLED == 1 ) - NvmCtx.ChannelsDefaultMask[0] = 0x00FF; - NvmCtx.ChannelsDefaultMask[1] = 0x0000; - NvmCtx.ChannelsDefaultMask[2] = 0x0000; - NvmCtx.ChannelsDefaultMask[3] = 0x0000; - NvmCtx.ChannelsDefaultMask[4] = 0x0001; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0x00FF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0x0001; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; #else - NvmCtx.ChannelsDefaultMask[0] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[1] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[2] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[3] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[4] = 0x00FF; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0x00FF; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; #endif /* HYBRID_ENABLED == 1 */ /* ST_WORKAROUND_END */ // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); // Copy into channels mask remaining - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: @@ -464,19 +428,11 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params ) case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; - } - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } @@ -485,16 +441,12 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionAU915GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionAU915NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_AU915 */ } bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_AU915 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -537,10 +489,14 @@ bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_AU915 */ } void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_AU915 ) // Size of the optional CF list must be 16 byte if( applyCFList->Size != 16 ) { @@ -556,62 +512,68 @@ void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList ) // ChMask0 - ChMask4 must be set (every ChMask has 16 bit) for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 4; chMaskItr++, cntPayload+=2 ) { - NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); - NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); + RegionNvmGroup2->ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); + RegionNvmGroup2->ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); if( chMaskItr == 4 ) { - NvmCtx.ChannelsMask[chMaskItr] = NvmCtx.ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsMask[chMaskItr] = RegionNvmGroup2->ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; } // Set the channel mask to the remaining - NvmCtx.ChannelsMaskRemaining[chMaskItr] &= NvmCtx.ChannelsMask[chMaskItr]; + RegionNvmGroup1->ChannelsMaskRemaining[chMaskItr] &= RegionNvmGroup2->ChannelsMask[chMaskItr]; } +#endif /* REGION_AU915 */ } bool RegionAU915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_AU915 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); - NvmCtx.ChannelsDefaultMask[4] = NvmCtx.ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[4] = RegionNvmGroup2->ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; - for( uint8_t i = 0; i < 6; i++ ) + for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_AU915 */ } void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_AU915 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, AU915_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsAU915 ); - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesAU915[rxConfigParams->Datarate], BandwidthsAU915[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesAU915[rxConfigParams->Datarate], BandwidthsAU915[rxConfigParams->Datarate] ); - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_AU915 */ } bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_AU915 ) int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; @@ -636,6 +598,7 @@ bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) // Radio configuration Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterDwell0AU915[dr]; @@ -645,44 +608,55 @@ bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) maxPayload = MaxPayloadOfDatarateDwell0AU915[dr]; } Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_AU915 */ } bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_AU915 ) int8_t phyDr = DataratesAU915[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsAU915 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Setup maximum payload length of the radio driver Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen ); + // Update time-on-air *txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen ); *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_AU915 */ } uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_AU915 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -692,7 +666,7 @@ uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; // Initialize local copy of channels mask - RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, 6 ); + RegionCommonChanMaskCopy( channelsMask, RegionNvmGroup2->ChannelsMask, 6 ); while( bytesProcessed < linkAdrReq->PayloadSize ) { @@ -810,7 +784,7 @@ uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = channelsMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = AU915_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = AU915_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = AU915_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -822,14 +796,14 @@ uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Copy Mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 ); - - NvmCtx.ChannelsMaskRemaining[0] &= NvmCtx.ChannelsMask[0]; - NvmCtx.ChannelsMaskRemaining[1] &= NvmCtx.ChannelsMask[1]; - NvmCtx.ChannelsMaskRemaining[2] &= NvmCtx.ChannelsMask[2]; - NvmCtx.ChannelsMaskRemaining[3] &= NvmCtx.ChannelsMask[3]; - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; - NvmCtx.ChannelsMaskRemaining[5] = NvmCtx.ChannelsMask[5]; + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, channelsMask, 6 ); + + RegionNvmGroup1->ChannelsMaskRemaining[0] &= RegionNvmGroup2->ChannelsMask[0]; + RegionNvmGroup1->ChannelsMaskRemaining[1] &= RegionNvmGroup2->ChannelsMask[1]; + RegionNvmGroup1->ChannelsMaskRemaining[2] &= RegionNvmGroup2->ChannelsMask[2]; + RegionNvmGroup1->ChannelsMaskRemaining[3] &= RegionNvmGroup2->ChannelsMask[3]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[5] = RegionNvmGroup2->ChannelsMask[5]; } // Update status variables @@ -838,12 +812,14 @@ uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_AU915 */ return status; } uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_AU915 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -868,13 +844,14 @@ uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_AU915 */ return status; } -uint8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq ) { - // Datarate and frequency KO - return 0; + // Do not accept the request + return -1; } int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) @@ -883,32 +860,44 @@ int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) return 0; } -uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { - return 0; + // Do not accept the request + return -1; } int8_t RegionAU915AlternateDr( int8_t currentDr, AlternateDrType_t type ) { - static int8_t trialsCount = 0; - - // Re-enable 500 kHz default channels - NvmCtx.ChannelsMask[4] = CHANNELS_MASK_500KHZ_MASK; +#if defined( REGION_AU915 ) + // Alternates the data rate according to the channel sequence: + // Eight times a 125kHz DR_2 and then one 500kHz DR_6 channel + if( type == ALTERNATE_DR ) + { + RegionNvmGroup1->JoinTrialsCounter++; + } + else + { + RegionNvmGroup1->JoinTrialsCounter--; + } - if( ( trialsCount & 0x01 ) == 0x01 ) + if( RegionNvmGroup1->JoinTrialsCounter % 9 == 0 ) { + // Use DR_6 every 9th times. currentDr = DR_6; } else { currentDr = DR_2; } - trialsCount++; return currentDr; +#else + return -1; +#endif /* REGION_AU915 */ } LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_AU915 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[AU915_MAX_NB_CHANNELS] = { 0 }; @@ -917,27 +906,29 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; // Count 125kHz channels - if( RegionCommonCountChannels( NvmCtx.ChannelsMaskRemaining, 0, 4 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup1->ChannelsMaskRemaining, 0, 4 ) == 0 ) { // Reactivate default channels - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 4 ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, 4 ); + + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; } // Check other channels if( nextChanParams->Datarate >= DR_6 ) { - if( ( NvmCtx.ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) + if( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) { - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; } } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMaskRemaining; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup1->ChannelsMaskRemaining; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = AU915_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = 0; + countChannelsParams.JoinChannels = NULL; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -955,12 +946,47 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_ if( status == LORAMAC_STATUS_OK ) { - // We found a valid channel - *channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; + if( nextChanParams->Joined == true ) + { + // Choose randomly on of the remaining channels + *channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; + } + else + { + // For rapid network acquisition in mixed gateway channel plan environments, the device + // follow a random channel selection sequence. It probes alternating one out of a + // group of eight 125 kHz channels followed by probing one 500 kHz channel each pass. + // Each time a 125 kHz channel will be selected from another group. + + // 125kHz Channels (0 - 63) DR2 + if( nextChanParams->Datarate == DR_2 ) + { + if( RegionBaseUSComputeNext125kHzJoinChannel( ( uint16_t* ) RegionNvmGroup1->ChannelsMaskRemaining, + &RegionNvmGroup1->JoinChannelGroupsCurrentIndex, channel ) == LORAMAC_STATUS_PARAMETER_INVALID ) + { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + } + // 500kHz Channels (64 - 71) DR6 + else + { + // Choose the next available channel + uint8_t i = 0; + while( ( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 ) + { + i++; + } + *channel = 64 + i; + } + } + // Disable the channel in the mask - RegionCommonChanDisable( NvmCtx.ChannelsMaskRemaining, *channel, AU915_MAX_NB_CHANNELS - 8 ); + RegionCommonChanDisable( RegionNvmGroup1->ChannelsMaskRemaining, *channel, AU915_MAX_NB_CHANNELS ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_AU915 */ } LoRaMacStatus_t RegionAU915ChannelAdd( ChannelAddParams_t* channelAdd ) @@ -975,18 +1001,21 @@ bool RegionAU915ChannelsRemove( ChannelRemoveParams_t* channelRemove ) void RegionAU915SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_AU915 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_AU915 */ } uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_AU915 ) int8_t datarate = DatarateOffsetsAU915[dr][drOffset]; if( datarate < 0 ) @@ -1001,10 +1030,14 @@ uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d } } return datarate; +#else + return 0; +#endif /* REGION_AU915 */ } void RegionAU915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_AU915 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesAU915; @@ -1019,4 +1052,5 @@ void RegionAU915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = AU915_BEACON_CHANNEL_DR; +#endif /* REGION_AU915 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.h index 98ace49f..896f7329 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionAU915.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionAU915.h + * @author MCD Application Team + * @brief Region definition for AU915 + ****************************************************************************** + */ #ifndef __REGION_AU915_H__ #define __REGION_AU915_H__ @@ -57,7 +67,7 @@ extern "C" /*! * Maximal datarate that can be used by the node */ -#define AU915_TX_MAX_DATARATE DR_13 +#define AU915_TX_MAX_DATARATE DR_6 /*! * Minimal datarate that can be used by the node @@ -88,12 +98,7 @@ extern "C" /*! * Maximal Rx1 receive datarate offset */ -#define AU915_MAX_RX1_DR_OFFSET 6 - -/*! - * Default Rx1 receive datarate offset - */ -#define AU915_DEFAULT_RX1_DR_OFFSET 0 +#define AU915_MAX_RX1_DR_OFFSET 5 /*! * Minimal Tx output power that can be used by the node @@ -115,11 +120,6 @@ extern "C" */ #define AU915_DEFAULT_UPLINK_DWELL_TIME 1 -/*! - * Default downlink dwell time configuration - */ -#define AU915_DEFAULT_DOWNLINK_DWELL_TIME 0 - /*! * Default Max EIRP */ @@ -130,16 +130,6 @@ extern "C" */ #define AU915_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define AU915_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define AU915_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -150,41 +140,6 @@ extern "C" */ #define AU915_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define AU915_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define AU915_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define AU915_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define AU915_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define AU915_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define AU915_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define AU915_ACK_TIMEOUT_RND 1000 - /*! * Second reception window channel frequency definition. */ @@ -213,11 +168,6 @@ extern "C" */ #define AU915_PING_SLOT_CHANNEL_FREQ 923300000 -/*! - * Number of possible ping slot channels - */ -#define AU915_PING_SLOT_NB_CHANNELS 8 - /*! * Number of possible beacon channels */ @@ -264,9 +214,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 % +#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 100.0 % /*! * Defines the first channel for RX window 1 for US band @@ -307,6 +257,7 @@ static const int8_t DatarateOffsetsAU915[7][6] = { DR_13, DR_13, DR_12, DR_11, DR_10, DR_9 }, // DR_6 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. * The table is valid for the dwell time configuration of 0 for uplinks. @@ -332,6 +283,7 @@ static const uint8_t MaxPayloadOfDatarateDwell1AU915[] = { 0, 0, 11, 53, 125, 24 * repeater support. */ static const uint8_t MaxPayloadOfDatarateRepeaterDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 33, 109, 222, 222, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -356,15 +308,6 @@ void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionAU915InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionAU915GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -457,7 +400,7 @@ uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -477,7 +420,7 @@ int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionBaseUS.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionBaseUS.c new file mode 100644 index 00000000..00e52d9c --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionBaseUS.c @@ -0,0 +1,153 @@ +/*! + * \file RegionBaseUS.c + * + * \brief Implementations common with US region. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \author Phanindra Kumar Yellapu ( STACKFORCE ) + */ +#include "LoRaMacTypes.h" +#include "Region/Region.h" +#include "RegionBaseUS.h" + + +/*! + * \brief Searches for available 125 kHz channels in the given channel mask. + * + * \param [IN] currentChannelMaskLeft The remaining channel mask. + * + * \param [OUT] findAvailableChannelsIndex List containing the indexes of all available 125 kHz channels. + * + * \param [OUT] availableChannels Number of available 125 kHz channels. + * + * \retval Status + */ +static LoRaMacStatus_t FindAvailable125kHzChannels( uint16_t currentChannelMaskLeft, + uint8_t* findAvailableChannelsIndex, uint8_t* availableChannels ) +{ + // Nullpointer check + if( findAvailableChannelsIndex == NULL || availableChannels == NULL ) + { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + // Initialize counter + *availableChannels = 0; + for( uint8_t i = 0; i < 8; i++ ) + { + // Find available channels + if( ( currentChannelMaskLeft & ( 1 << i ) ) != 0 ) + { + // Save available channel index + findAvailableChannelsIndex[*availableChannels] = i; + // Increment counter of available channels if the current channel is available + ( *availableChannels )++; + } + } + + return LORAMAC_STATUS_OK; +} + +LoRaMacStatus_t RegionBaseUSComputeNext125kHzJoinChannel( uint16_t* channelsMaskRemaining, + uint8_t* groupsCurrentIndex, uint8_t* newChannelIndex ) +{ + uint8_t currentChannelMaskLeftIndex; + uint16_t currentChannelMaskLeft; + uint8_t findAvailableChannelsIndex[8] = { 0 }; + uint8_t availableChannels = 0; + uint8_t startIndex; + + // Null pointer check + if( channelsMaskRemaining == NULL || groupsCurrentIndex == NULL || newChannelIndex == NULL ) + { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + // copy the current index. + startIndex = *groupsCurrentIndex; + + do + { + // Current ChannelMaskRemaining, two groups per channel mask. For example Group 0 and 1 (8 bit) are ChannelMaskRemaining 0 (16 bit), etc. + currentChannelMaskLeftIndex = (uint8_t) startIndex / 2; + + // For even numbers we need the 8 LSBs and for uneven the 8 MSBs + if( ( startIndex % 2 ) == 0 ) + { + currentChannelMaskLeft = ( channelsMaskRemaining[currentChannelMaskLeftIndex] & 0x00FF ); + } + else + { + currentChannelMaskLeft = ( ( channelsMaskRemaining[currentChannelMaskLeftIndex] >> 8 ) & 0x00FF ); + } + + + if( FindAvailable125kHzChannels( currentChannelMaskLeft, findAvailableChannelsIndex, &availableChannels ) == LORAMAC_STATUS_PARAMETER_INVALID ) + { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + if ( availableChannels > 0 ) + { + // Choose randomly a free channel 125kHz + *newChannelIndex = ( startIndex * 8 ) + findAvailableChannelsIndex[randr( 0, ( availableChannels - 1 ) )]; + } + + // Increment start index + startIndex++; + if ( startIndex > 7 ) + { + startIndex = 0; + } + } while( ( availableChannels == 0 ) && ( startIndex != *groupsCurrentIndex ) ); + + if ( availableChannels > 0 ) + { + *groupsCurrentIndex = startIndex; + return LORAMAC_STATUS_OK; + } + + return LORAMAC_STATUS_PARAMETER_INVALID; +} + +bool RegionBaseUSVerifyFrequencyGroup( uint32_t freq, uint32_t minFreq, uint32_t maxFreq, uint32_t stepwidth ) +{ + if( ( freq < minFreq ) || + ( freq > maxFreq ) || + ( ( ( freq - ( uint32_t ) minFreq ) % ( uint32_t ) stepwidth ) != 0 ) ) + { + return false; + } + return true; +} + +uint32_t RegionBaseUSCalcDownlinkFrequency( uint8_t channel, uint32_t frequency, + uint32_t stepwidth ) +{ + // Calculate the frequency + return frequency + ( channel * stepwidth ); +} diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionBaseUS.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionBaseUS.h new file mode 100644 index 00000000..72edfb5b --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionBaseUS.h @@ -0,0 +1,98 @@ +/*! + * \file RegionBaseUS.h + * + * \brief Implementations common with US region. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \author Phanindra Kumar Yellapu ( STACKFORCE ) + * + * \defgroup REGIONBASEUS US region common implementations. + * \{ + */ +#ifndef __REGIONBASEUS_H__ +#define __REGIONBASEUS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "LoRaMac.h" + +/*! + * \brief Computes the next 125kHz channel used for join requests. + * And it returns all the parameters updated. + * + * \param [IN] channelsMaskRemaining pointer to remaining channels. + * + * \param [IN] groupsCurrentIndex Index of current channel. + * + * \param [OUT] newChannelIndex Index of next available channel. + * + * \retval Status + */ +LoRaMacStatus_t RegionBaseUSComputeNext125kHzJoinChannel( uint16_t* channelsMaskRemaining, + uint8_t* groupsCurrentIndex, uint8_t* newChannelIndex ); + +/*! + * \brief Verifies if the frequency is in the correct range with a + * specific stepwidth. + * + * \param [IN] freq Frequency to verify. + * + * \param [IN] minFreq Minimum frequency. + * + * \param [IN] maxFreq Maximum frequency. + * + * \param [IN] stepwidth Frequency stepwidth. + * + * \retval True, if the frequency is valid, false if not. + */ +bool RegionBaseUSVerifyFrequencyGroup( uint32_t freq, uint32_t minFreq, uint32_t maxFreq, uint32_t stepwidth ); + +/*! + * \brief Calculates the downlink frequency for a given channel. This + * function is used in class B only. + * + * \param [IN] channel The channel according to the channel plan. + * + * \param [IN] frequency The base frequency. + * + * \param [IN] stepwidth The frequency stepwidth. + * + * \retval The downlink frequency. + */ +uint32_t RegionBaseUSCalcDownlinkFrequency( uint8_t channel, uint32_t frequency, + uint32_t stepwidth ); + +/*! \} defgroup REGIONBASEUS */ + +#ifdef __cplusplus +} +#endif + +#endif // __REGIONBASEUS_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.c index 536f7f3b..2230940d 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.c @@ -28,82 +28,33 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionCN470.c + * @author MCD Application Team + * @brief Region implementation for CN470 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionCN470.h" +#include "RegionBaseUS.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 6 -/*! - * Region specific context - */ -typedef struct sRegionCN470NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ CN470_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ CN470_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionCN470NvmCtx_t; - +#if defined( REGION_CN470 ) /* * Non-volatile module context. */ -static RegionCN470NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsCN470[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - static bool VerifyRfFreq( uint32_t freq ) { // Check radio driver support @@ -131,15 +82,17 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesCN470[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsCN470 ); return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true ); } +#endif /* REGION_CN470 */ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_CN470 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -159,7 +112,16 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, CN470_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )CN470_TX_MAX_DATARATE, + .MinDr = ( int8_t )CN470_TX_MIN_DATARATE, + .NbChannels = CN470_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -174,12 +136,12 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = CN470_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = CN470_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -187,11 +149,13 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateCN470[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterCN470[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = CN470_DUTY_CYCLE_ENABLED; @@ -204,37 +168,37 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = CN470_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = CN470_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = CN470_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = CN470_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = CN470_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( CN470_ACKTIMEOUT + randr( -CN470_ACK_TIMEOUT_RND, CN470_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = CN470_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -249,12 +213,12 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -264,13 +228,17 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = CN470_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -285,7 +253,9 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BEACON_CHANNEL_FREQ: { - phyParam.Value = CN470_BEACON_CHANNEL_FREQ; + phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel, + CN470_BEACON_CHANNEL_FREQ, + CN470_BEACON_CHANNEL_STEPWIDTH ); break; } case PHY_BEACON_FORMAT: @@ -300,16 +270,6 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = CN470_BEACON_CHANNEL_DR; break; } - case PHY_BEACON_CHANNEL_STEPWIDTH: - { - phyParam.Value = CN470_BEACON_CHANNEL_STEPWIDTH; - break; - } - case PHY_PING_SLOT_NB_CHANNELS: - { - phyParam.Value = CN470_PING_SLOT_NB_CHANNELS; - break; - } case PHY_BEACON_NB_CHANNELS: { phyParam.Value = CN470_BEACON_NB_CHANNELS; @@ -317,7 +277,9 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_PING_SLOT_CHANNEL_FREQ: { - phyParam.Value = CN470_PING_SLOT_CHANNEL_FREQ; + phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel, + CN470_PING_SLOT_CHANNEL_FREQ, + CN470_BEACON_CHANNEL_STEPWIDTH ); break; } case PHY_PING_SLOT_CHANNEL_DR: @@ -325,6 +287,11 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = CN470_PING_SLOT_CHANNEL_DR; break; } + case PHY_PING_SLOT_NB_CHANNELS: + { + phyParam.Value = CN470_BEACON_NB_CHANNELS; + break; + } case PHY_SF_FROM_DR: { phyParam.Value = DataratesCN470[getPhy->Datarate]; @@ -332,7 +299,7 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsCN470 ); break; } default: @@ -341,17 +308,21 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_CN470 */ return phyParam; } void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_CN470 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_CN470 */ } void RegionCN470InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_CN470 ) Band_t bands[CN470_MAX_NB_BANDS] = { CN470_BAND0 @@ -361,40 +332,48 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS ); - // Channels + // Default channels for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ ) { // 125 kHz channels - NvmCtx.Channels[i].Frequency = 470300000 + i * 200000; - NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 470300000 + i * 200000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; + RegionNvmGroup2->Channels[i].Band = 0; } - // Initialize channels default mask + // Default ChannelsMask /* ST_WORKAROUND_BEGIN: Hybrid mode */ #if ( HYBRID_ENABLED == 1 ) - NvmCtx.ChannelsDefaultMask[0] = 0x00FF; - NvmCtx.ChannelsDefaultMask[1] = 0x0000; - NvmCtx.ChannelsDefaultMask[2] = 0x0000; - NvmCtx.ChannelsDefaultMask[3] = 0x0000; - NvmCtx.ChannelsDefaultMask[4] = 0x0000; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0x00FF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; #else - NvmCtx.ChannelsDefaultMask[0] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[1] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[2] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[3] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[4] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[5] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0xFFFF; #endif /* HYBRID_ENABLED == 1 */ /* ST_WORKAROUND_END */ // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: @@ -404,15 +383,7 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params ) case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } default: @@ -420,16 +391,12 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionCN470GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionCN470NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_CN470 */ } bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_CN470 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -458,10 +425,14 @@ bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_CN470 */ } void RegionCN470ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_CN470 ) // Size of the optional CF list must be 16 byte if( applyCFList->Size != 16 ) { @@ -477,48 +448,54 @@ void RegionCN470ApplyCFList( ApplyCFListParams_t* applyCFList ) // ChMask0 - ChMask5 must be set (every ChMask has 16 bit) for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 5; chMaskItr++, cntPayload+=2 ) { - NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); - NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); + RegionNvmGroup2->ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); + RegionNvmGroup2->ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); } +#endif /* REGION_CN470 */ } bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_CN470 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_CN470 */ } void RegionCN470ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_CN470 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, CN470_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsCN470 ); - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesCN470[rxConfigParams->Datarate], BandwidthsCN470[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesCN470[rxConfigParams->Datarate], BandwidthsCN470[rxConfigParams->Datarate] ); - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_CN470 */ } bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_CN470 ) int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; @@ -542,7 +519,7 @@ bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) // Radio configuration Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); - + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr]; @@ -552,53 +529,65 @@ bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) maxPayload = MaxPayloadOfDatarateCN470[dr]; } Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_CN470 */ } bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_CN470 ) int8_t phyDr = DataratesCN470[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsCN470 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); - Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); + Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Setup maximum payload length of the radio driver Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen ); + // Update time-on-air *txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen ); - *txPower = txPowerLimited; + *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_CN470 */ } uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_CN470 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; - uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t channelsMask[CHANNELS_MASK_SIZE] = { 0, 0, 0, 0, 0, 0 }; GetPhyParams_t getPhy; PhyParam_t phyParam; RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; // Initialize local copy of channels mask - RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, 6 ); + RegionCommonChanMaskCopy( channelsMask, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); while( bytesProcessed < linkAdrReq->PayloadSize ) { @@ -633,7 +622,7 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in for( uint8_t i = 0; i < 16; i++ ) { if( ( ( linkAdrParams.ChMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -659,7 +648,7 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = channelsMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = CN470_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = CN470_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = CN470_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -671,7 +660,7 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Copy Mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, channelsMask, 6 ); } // Update status variables @@ -680,12 +669,14 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_CN470 */ return status; } uint8_t RegionCN470RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_CN470 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -705,32 +696,40 @@ uint8_t RegionCN470RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_CN470 */ return status; } -uint8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq ) { - // Datarate and frequency KO - return 0; + // Do not accept the request + return -1; } int8_t RegionCN470TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { - return 0; + // Do not accept the request + return -1; } int8_t RegionCN470AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_CN470 ) return currentDr; +#else + return -1; +#endif /* REGION_CN470 */ } LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_CN470 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[CN470_MAX_NB_CHANNELS] = { 0 }; @@ -739,24 +738,24 @@ LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; // Count 125kHz channels - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 6 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, CHANNELS_MASK_SIZE ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] = 0xFFFF; - NvmCtx.ChannelsMask[1] = 0xFFFF; - NvmCtx.ChannelsMask[2] = 0xFFFF; - NvmCtx.ChannelsMask[3] = 0xFFFF; - NvmCtx.ChannelsMask[4] = 0xFFFF; - NvmCtx.ChannelsMask[5] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[4] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[5] = 0xFFFF; } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = CN470_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = 0; + countChannelsParams.JoinChannels = NULL; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -778,6 +777,9 @@ LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_ *channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_CN470 */ } LoRaMacStatus_t RegionCN470ChannelAdd( ChannelAddParams_t* channelAdd ) @@ -792,18 +794,21 @@ bool RegionCN470ChannelsRemove( ChannelRemoveParams_t* channelRemove ) void RegionCN470SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_CN470 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_CN470 */ } uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_CN470 ) int8_t datarate = dr - drOffset; if( datarate < 0 ) @@ -811,10 +816,14 @@ uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d datarate = DR_0; } return datarate; +#else + return 0; +#endif /* REGION_CN470 */ } void RegionCN470RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_CN470 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesCN470; @@ -829,4 +838,5 @@ void RegionCN470RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = CN470_BEACON_CHANNEL_DR; +#endif /* REGION_CN470 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.h index 0da8d493..8bab4ca1 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN470.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionCN470.h + * @author MCD Application Team + * @brief Region definition for CN470 + ****************************************************************************** + */ #ifndef __REGION_CN470_H__ #define __REGION_CN470_H__ @@ -47,7 +57,7 @@ extern "C" /*! * LoRaMac maximum number of channels */ -#define CN470_MAX_NB_CHANNELS 96 +#define CN470_MAX_NB_CHANNELS 96 /*! * Minimal datarate that can be used by the node @@ -82,27 +92,22 @@ extern "C" /*! * Maximal Rx1 receive datarate offset */ -#define CN470_MAX_RX1_DR_OFFSET 3 - -/*! - * Default Rx1 receive datarate offset - */ -#define CN470_DEFAULT_RX1_DR_OFFSET 0 +#define CN470_MAX_RX1_DR_OFFSET 5 /*! * Minimal Tx output power that can be used by the node */ -#define CN470_MIN_TX_POWER TX_POWER_7 +#define CN470_MIN_TX_POWER TX_POWER_7 /*! * Maximal Tx output power that can be used by the node */ -#define CN470_MAX_TX_POWER TX_POWER_0 +#define CN470_MAX_TX_POWER TX_POWER_0 /*! * Default Tx output power used by the node */ -#define CN470_DEFAULT_TX_POWER TX_POWER_0 +#define CN470_DEFAULT_TX_POWER TX_POWER_0 /*! * Default Max EIRP @@ -114,16 +119,6 @@ extern "C" */ #define CN470_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define CN470_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define CN470_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -134,41 +129,6 @@ extern "C" */ #define CN470_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define CN470_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define CN470_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define CN470_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define CN470_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define CN470_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define CN470_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define CN470_ACK_TIMEOUT_RND 1000 - /*! * Second reception window channel frequency definition. */ @@ -179,6 +139,11 @@ extern "C" */ #define CN470_RX_WND_2_DR DR_0 +/*! + * Default uplink dwell time configuration + */ +#define CN470_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -197,11 +162,6 @@ extern "C" */ #define CN470_PING_SLOT_CHANNEL_FREQ 508300000 -/*! - * Number of possible ping slot channels - */ -#define CN470_PING_SLOT_NB_CHANNELS 8 - /*! * Number of possible beacon channels */ @@ -244,9 +204,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 % +#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 100.0 % /*! * Defines the first channel for RX window 1 for CN470 band @@ -273,6 +233,7 @@ static const uint8_t DataratesCN470[] = { 12, 11, 10, 9, 8, 7 }; */ static const uint32_t BandwidthsCN470[] = { 125000, 125000, 125000, 125000, 125000, 125000 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ @@ -282,6 +243,7 @@ static const uint8_t MaxPayloadOfDatarateCN470[] = { 51, 51, 51, 115, 242, 242 } * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterCN470[] = { 51, 51, 51, 115, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -306,15 +268,6 @@ void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionCN470InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionCN470GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -407,7 +360,7 @@ uint8_t RegionCN470RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -427,13 +380,15 @@ int8_t RegionCN470TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. * * \param [IN] currentDr Current datarate. * + * \param [IN] type Alternation type. + * * \retval Datarate to apply. */ int8_t RegionCN470AlternateDr( int8_t currentDr, AlternateDrType_t type ); @@ -495,7 +450,7 @@ uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d * * \param [IN] rxBeaconSetup Pointer to the function parameters */ - void RegionCN470RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ); +void RegionCN470RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ); /*! \} defgroup REGIONCN470 */ diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.c index edcc241d..f0b40e66 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.c @@ -28,82 +28,32 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionCN779.c + * @author MCD Application Team + * @brief Region implementation for CN779 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionCN779.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionCN779NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ CN779_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ CN779_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionCN779NvmCtx_t; - +#if defined( REGION_CN779 ) /* * Non-volatile module context. */ -static RegionCN779NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsCN779[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - static bool VerifyRfFreq( uint32_t freq ) { // Check radio driver support @@ -122,7 +72,7 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesCN779[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsCN779 ); TimerTime_t timeOnAir = 0; if( datarate == DR_7 ) @@ -135,11 +85,13 @@ static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) } return timeOnAir; } +#endif /* REGION_CN779 */ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_CN779 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -159,7 +111,16 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, CN779_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )CN779_TX_MAX_DATARATE, + .MinDr = ( int8_t )CN779_TX_MIN_DATARATE, + .NbChannels = CN779_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -174,12 +135,12 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = CN779_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = CN779_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -187,11 +148,13 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateCN779[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterCN779[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = CN779_DUTY_CYCLE_ENABLED; @@ -204,37 +167,37 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = CN779_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = CN779_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = CN779_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = CN779_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = CN779_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( CN779_ACKTIMEOUT + randr( -CN779_ACK_TIMEOUT_RND, CN779_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = CN779_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -249,12 +212,12 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -264,13 +227,17 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = CN779_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -317,7 +284,7 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsCN779 ); break; } default: @@ -326,17 +293,21 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_CN779 */ return phyParam; } void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_CN779 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_CN779 */ } void RegionCN779InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_CN779 ) Band_t bands[CN779_MAX_NB_BANDS] = { CN779_BAND0 @@ -346,43 +317,43 @@ void RegionCN779InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN779_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN779_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) CN779_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) CN779_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) CN779_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) CN779_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) CN779_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) CN779_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -390,16 +361,12 @@ void RegionCN779InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionCN779GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionCN779NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_CN779 */ } bool RegionCN779Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_CN779 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -431,10 +398,14 @@ bool RegionCN779Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_CN779 */ } void RegionCN779ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_CN779 ) ChannelParams_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; @@ -490,52 +461,58 @@ void RegionCN779ApplyCFList( ApplyCFListParams_t* applyCFList ) RegionCN779ChannelsRemove( &channelRemove ); } } +#endif /* REGION_CN779 */ } bool RegionCN779ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_CN779 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_CN779 */ } void RegionCN779ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_CN779 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, CN779_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsCN779 ); if( rxConfigParams->Datarate == DR_7 ) { // FSK - tSymbol = RegionCommonComputeSymbolTimeFsk( DataratesCN779[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeFsk( DataratesCN779[rxConfigParams->Datarate] ); } else { // LoRa - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesCN779[rxConfigParams->Datarate], BandwidthsCN779[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesCN779[rxConfigParams->Datarate], BandwidthsCN779[rxConfigParams->Datarate] ); } - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_CN779 */ } bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_CN779 ) RadioModems_t modem; int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; @@ -550,11 +527,11 @@ bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -575,6 +552,7 @@ bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterCN779[dr]; @@ -584,27 +562,33 @@ bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) maxPayload = MaxPayloadOfDatarateCN779[dr]; } Radio.SetMaxPayloadLength( modem, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_CN779 */ } bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_CN779 ) RadioModems_t modem; int8_t phyDr = DataratesCN779[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsCN779 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -617,7 +601,7 @@ bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); } /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Update time-on-air @@ -628,11 +612,15 @@ bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_CN779 */ } uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_CN779 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -675,7 +663,7 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -683,7 +671,7 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -709,7 +697,7 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = CN779_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = CN779_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = CN779_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -721,9 +709,9 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -732,12 +720,14 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_CN779 */ return status; } uint8_t RegionCN779RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_CN779 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -757,10 +747,11 @@ uint8_t RegionCN779RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_CN779 */ return status; } -uint8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq ) { uint8_t status = 0x03; ChannelAddParams_t channelAdd; @@ -815,12 +806,14 @@ uint8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq ) int8_t RegionCN779TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { uint8_t status = 0x03; +#if defined( REGION_CN779 ) // Verify if the frequency is supported if( VerifyRfFreq( dlChannelReq->Rx1Frequency ) == false ) @@ -829,7 +822,7 @@ uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -837,9 +830,10 @@ uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } +#endif /* REGION_CN779 */ return status; } @@ -850,26 +844,28 @@ int8_t RegionCN779AlternateDr( int8_t currentDr, AlternateDrType_t type ) LoRaMacStatus_t RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_CN779 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[CN779_MAX_NB_CHANNELS] = { 0 }; RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; + uint16_t joinChannels = CN779_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = CN779_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = CN779_JOIN_CHANNELS; + countChannelsParams.JoinChannels = &joinChannels; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -893,13 +889,17 @@ LoRaMacStatus_t RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_CN779 */ } LoRaMacStatus_t RegionCN779ChannelAdd( ChannelAddParams_t* channelAdd ) { +#if defined( REGION_CN779 ) bool drInvalid = false; bool freqInvalid = false; uint8_t id = channelAdd->ChannelId; @@ -951,14 +951,18 @@ LoRaMacStatus_t RegionCN779ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_CN779 */ } bool RegionCN779ChannelsRemove( ChannelRemoveParams_t* channelRemove ) { +#if defined( REGION_CN779 ) uint8_t id = channelRemove->ChannelId; if( id < CN779_NUMB_DEFAULT_CHANNELS ) @@ -967,25 +971,31 @@ bool RegionCN779ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, CN779_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, CN779_MAX_NB_CHANNELS ); +#else + return false; +#endif /* REGION_CN779 */ } void RegionCN779SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_CN779 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_CN779 */ } uint8_t RegionCN779ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_CN779 ) int8_t datarate = dr - drOffset; if( datarate < 0 ) @@ -993,10 +1003,14 @@ uint8_t RegionCN779ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d datarate = DR_0; } return datarate; +#else + return 0; +#endif /* REGION_CN779 */ } void RegionCN779RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_CN779 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesCN779; @@ -1011,4 +1025,5 @@ void RegionCN779RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = CN779_BEACON_CHANNEL_DR; +#endif /* REGION_CN779 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.h index 146dc6a7..8c5968bb 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCN779.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionCN779.h + * @author MCD Application Team + * @brief Region definition for CN779 + ****************************************************************************** + */ #ifndef __REGION_CN779_H__ #define __REGION_CN779_H__ @@ -94,11 +104,6 @@ extern "C" */ #define CN779_MAX_RX1_DR_OFFSET 5 -/*! - * Default Rx1 receive datarate offset - */ -#define CN779_DEFAULT_RX1_DR_OFFSET 0 - /*! * Minimal Tx output power that can be used by the node */ @@ -124,16 +129,6 @@ extern "C" */ #define CN779_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define CN779_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define CN779_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -144,41 +139,6 @@ extern "C" */ #define CN779_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define CN779_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define CN779_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define CN779_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define CN779_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define CN779_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define CN779_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define CN779_ACK_TIMEOUT_RND 1000 - /*! * Verification of default datarate */ @@ -196,6 +156,11 @@ extern "C" */ #define CN779_RX_WND_2_DR DR_0 +/*! + * Default uplink dwell time configuration + */ +#define CN779_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -246,9 +211,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 % +#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -282,6 +247,7 @@ static const uint8_t DataratesCN779[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; */ static const uint32_t BandwidthsCN779[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ @@ -291,6 +257,7 @@ static const uint8_t MaxPayloadOfDatarateCN779[] = { 51, 51, 51, 115, 242, 242, * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterCN779[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -315,15 +282,6 @@ void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionCN779InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionCN779GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -416,7 +374,7 @@ uint8_t RegionCN779RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -436,7 +394,7 @@ int8_t RegionCN779TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.c index 6cd34db6..cdf0630c 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.c @@ -28,31 +28,81 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionCommon.c + * @author MCD Application Team + * @brief LoRa MAC common region implementation + ****************************************************************************** + */ #include +#include "radio.h" +#include "utilities.h" #include "RegionCommon.h" +#include "systime.h" #include "mw_log_conf.h" #define BACKOFF_DC_1_HOUR 100 #define BACKOFF_DC_10_HOURS 1000 #define BACKOFF_DC_24_HOURS 10000 -#define BACKOFF_DC_TIMER_PERIOD_FACTOR 100 + +#define BACKOFF_DUTY_CYCLE_1_HOUR_IN_S 3600 +#define BACKOFF_DUTY_CYCLE_10_HOURS_IN_S ( BACKOFF_DUTY_CYCLE_1_HOUR_IN_S + ( BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 10 ) ) +#define BACKOFF_DUTY_CYCLE_24_HOURS_IN_S ( BACKOFF_DUTY_CYCLE_10_HOURS_IN_S + ( BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 24 ) ) +#define BACKOFF_24_HOURS_IN_S ( BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 24 ) #ifndef DUTY_CYCLE_TIME_PERIOD /*! - * Default duty cycle time period is 1 hour = 3600000 ms + * Default duty cycle observation time period + * + * \remark The ETSI observation time period is 1 hour (3600000 ms) but, the implemented algorithm may violate the + * defined duty-cycle restrictions. In order to ensure that these restrictions never get violated we changed the + * default duty cycle observation time period to 1/2 hour (1800000 ms). */ -#define DUTY_CYCLE_TIME_PERIOD 3600000 +#define DUTY_CYCLE_TIME_PERIOD 1800000 #endif +/*! + * \brief Returns `N / D` rounded to the smallest integer value greater than or equal to `N / D` + * + * \warning when `D == 0`, the result is undefined + * + * \remark `N` and `D` can be signed or unsigned + * + * \param [IN] N the numerator, which can have any sign + * \param [IN] D the denominator, which can have any sign + * \retval N / D with any fractional part rounded to the smallest integer value greater than or equal to `N / D` + */ +#define DIV_CEIL( N, D ) \ + ( \ + ( N > 0 ) ? \ + ( ( ( N ) + ( D ) - 1 ) / ( D ) ) : \ + ( ( N ) / ( D ) ) \ + ) + static uint16_t GetDutyCycle( Band_t* band, bool joined, SysTime_t elapsedTimeSinceStartup ) { - uint16_t joinDutyCycle = RegionCommonGetJoinDc( elapsedTimeSinceStartup ); uint16_t dutyCycle = band->DCycle; if( joined == false ) { - // Get the join duty cycle which depends on the runtime - joinDutyCycle = RegionCommonGetJoinDc( elapsedTimeSinceStartup ); + uint16_t joinDutyCycle = BACKOFF_DC_24_HOURS; + + if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_1_HOUR_IN_S ) + { + joinDutyCycle = BACKOFF_DC_1_HOUR; + } + else if( elapsedTimeSinceStartup.Seconds < BACKOFF_DUTY_CYCLE_10_HOURS_IN_S ) + { + joinDutyCycle = BACKOFF_DC_10_HOURS; + } + else + { + joinDutyCycle = BACKOFF_DC_24_HOURS; + } // Take the most restrictive duty cycle dutyCycle = MAX( dutyCycle, joinDutyCycle ); } @@ -66,10 +116,13 @@ static uint16_t GetDutyCycle( Band_t* band, bool joined, SysTime_t elapsedTimeSi return dutyCycle; } -static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedTimeSinceStartup ) +static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedTimeSinceStartup, + bool dutyCycleEnabled, bool lastTxIsJoinRequest ) { uint16_t dutyCycle = band->DCycle; - uint8_t timePeriodFactor = 1; + TimerTime_t maxCredits = DUTY_CYCLE_TIME_PERIOD; + TimerTime_t elapsedTime = SysTimeToMs( elapsedTimeSinceStartup ); + SysTime_t timeDiff = { 0 }; // Get the band duty cycle. If not joined, the function either returns the join duty cycle // or the band duty cycle, whichever is more restrictive. @@ -77,20 +130,60 @@ static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedT if( joined == false ) { - // Apply a factor to increase the maximum time period of observation - timePeriodFactor = dutyCycle / BACKOFF_DC_TIMER_PERIOD_FACTOR; - } + if( dutyCycle == BACKOFF_DC_1_HOUR ) + { + maxCredits = DUTY_CYCLE_TIME_PERIOD; + band->LastMaxCreditAssignTime = elapsedTime; + } + else if( dutyCycle == BACKOFF_DC_10_HOURS ) + { + maxCredits = DUTY_CYCLE_TIME_PERIOD * 10; + band->LastMaxCreditAssignTime = elapsedTime; + } + else + { + maxCredits = DUTY_CYCLE_TIME_PERIOD * 24; + } - // Setup the maximum allowed credits - band->MaxTimeCredits = DUTY_CYCLE_TIME_PERIOD * timePeriodFactor; + timeDiff = SysTimeSub( elapsedTimeSinceStartup, SysTimeFromMs( band->LastMaxCreditAssignTime ) ); - // In case if it is the first time, update also the current - // time credits + // Verify if we have to assign the maximum credits in cases + // of the preconditions have changed. + if( ( ( dutyCycleEnabled == false ) && ( lastTxIsJoinRequest == false ) ) || + ( band->MaxTimeCredits != maxCredits ) || + ( timeDiff.Seconds >= BACKOFF_24_HOURS_IN_S ) ) + { + band->TimeCredits = maxCredits; + + if( elapsedTimeSinceStartup.Seconds >= BACKOFF_DUTY_CYCLE_24_HOURS_IN_S ) + { + timeDiff.Seconds = ( elapsedTimeSinceStartup.Seconds - BACKOFF_DUTY_CYCLE_24_HOURS_IN_S ) / BACKOFF_24_HOURS_IN_S; + timeDiff.Seconds *= BACKOFF_24_HOURS_IN_S; + timeDiff.Seconds += BACKOFF_DUTY_CYCLE_24_HOURS_IN_S; + timeDiff.SubSeconds = 0; + band->LastMaxCreditAssignTime = SysTimeToMs( timeDiff ); + } + } + } + else + { + if( dutyCycleEnabled == false ) + { + // Assign max credits when the duty cycle is disabled. + band->TimeCredits = maxCredits; + } + } + + // Assign the max credits if its the first time if( band->LastBandUpdateTime == 0 ) { - band->TimeCredits = band->MaxTimeCredits; + band->TimeCredits = maxCredits; } + // Setup the maximum allowed credits. We can assign them + // safely all the time. + band->MaxTimeCredits = maxCredits; + return dutyCycle; } @@ -98,30 +191,15 @@ static uint16_t UpdateTimeCredits( Band_t* band, bool joined, bool dutyCycleEnab bool lastTxIsJoinRequest, SysTime_t elapsedTimeSinceStartup, TimerTime_t currentTime ) { - uint16_t dutyCycle = SetMaxTimeCredits( band, joined, elapsedTimeSinceStartup ); + uint16_t dutyCycle = SetMaxTimeCredits( band, joined, elapsedTimeSinceStartup, + dutyCycleEnabled, lastTxIsJoinRequest ); - if( joined == false ) + if( joined == true ) { - if( ( dutyCycleEnabled == false ) && - ( lastTxIsJoinRequest == false ) ) - { - // This is the case when the duty cycle is off and the last uplink frame was not a join. - // This could happen in case of a rejoin, e.g. in compliance test mode. - // In this special case we have to set the time off to 0, since the join duty cycle shall only - // be applied after the first join request. - band->TimeCredits = band->MaxTimeCredits; - } + // Apply a sliding window for the duty cycle with collection and speding + // credits. + band->TimeCredits += TimerGetElapsedTime( band->LastBandUpdateTime ); } - else - { - if( dutyCycleEnabled == false ) - { - band->TimeCredits = band->MaxTimeCredits; - } - } - - // Get the difference between now and the last update - band->TimeCredits += TimerGetElapsedTime( band->LastBandUpdateTime ); // Limit band credits to maximum if( band->TimeCredits > band->MaxTimeCredits ) @@ -149,25 +227,6 @@ static uint8_t CountChannels( uint16_t mask, uint8_t nbBits ) return nbActiveBits; } -uint16_t RegionCommonGetJoinDc( SysTime_t elapsedTime ) -{ - uint16_t dutyCycle = 0; - - if( elapsedTime.Seconds < 3600 ) - { - dutyCycle = BACKOFF_DC_1_HOUR; - } - else if( elapsedTime.Seconds < ( 3600 + 36000 ) ) - { - dutyCycle = BACKOFF_DC_10_HOURS; - } - else - { - dutyCycle = BACKOFF_DC_24_HOURS; - } - return dutyCycle; -} - bool RegionCommonChanVerifyDr( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, int8_t minDr, int8_t maxDr, ChannelParams_t* channels ) { if( RegionCommonValueInRange( dr, minDr, maxDr ) == 0 ) @@ -289,7 +348,7 @@ TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands, // when the duty cycle is off, or the TimeCredits of the band // is higher than the credit costs for the transmission. if( ( bands[i].TimeCredits > creditCosts ) || - ( dutyCycleEnabled == false ) ) + ( ( dutyCycleEnabled == false ) && ( joined == true ) ) ) { bands[i].ReadyForTransmission = true; // This band is a potential candidate for an @@ -315,6 +374,36 @@ TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands, // at the moment), so increase the counter. validBands++; } + + // Apply a special calculation if the device is not joined. + if( joined == false ) + { + SysTime_t backoffTimeRange = { + .Seconds = 0, + .SubSeconds = 0, + }; + // Get the backoff time range based on the duty cycle definition + if( dutyCycle == BACKOFF_DC_1_HOUR ) + { + backoffTimeRange.Seconds = BACKOFF_DUTY_CYCLE_1_HOUR_IN_S; + } + else if( dutyCycle == BACKOFF_DC_10_HOURS ) + { + backoffTimeRange.Seconds = BACKOFF_DUTY_CYCLE_10_HOURS_IN_S; + } + else + { + backoffTimeRange.Seconds = BACKOFF_DUTY_CYCLE_24_HOURS_IN_S; + } + // Calculate the time to wait. + if( elapsedTimeSinceStartup.Seconds > BACKOFF_DUTY_CYCLE_24_HOURS_IN_S ) + { + backoffTimeRange.Seconds += BACKOFF_24_HOURS_IN_S * ( ( ( elapsedTimeSinceStartup.Seconds - BACKOFF_DUTY_CYCLE_24_HOURS_IN_S ) / BACKOFF_24_HOURS_IN_S ) + 1 ); + } + // Calculate the time difference between now and the next range + backoffTimeRange = SysTimeSub( backoffTimeRange, elapsedTimeSinceStartup ); + minTimeToWait = SysTimeToMs( backoffTimeRange ); + } } } @@ -409,24 +498,23 @@ uint8_t RegionCommonLinkAdrReqVerifyParams( RegionCommonLinkAdrReqVerifyParams_t return status; } -/* ST_WORKAROUND_BEGIN: remove float/double */ -uint32_t RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidth ) +uint32_t RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidthInHz ) { - return (1000000000UL/bandwidth) * (1 << phyDr); + return ( 1 << phyDr ) * 1000000 / bandwidthInHz; } -uint32_t RegionCommonComputeSymbolTimeFsk( uint8_t phyDr ) +uint32_t RegionCommonComputeSymbolTimeFsk( uint8_t phyDrInKbps ) { - // ((8 * 1000000) / 50); - return 160000UL; + return 8000 / ( uint32_t )phyDrInKbps; // 1 symbol equals 1 byte } -void RegionCommonComputeRxWindowParameters( uint32_t tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset ) +void RegionCommonComputeRxWindowParameters( uint32_t tSymbolInUs, uint8_t minRxSymbols, uint32_t rxErrorInMs, uint32_t wakeUpTimeInMs, uint32_t* windowTimeoutInSymbols, int32_t* windowOffsetInMs ) { - *windowTimeout = MAX( (uint32_t)2 * minRxSymbols - 8 + DIVC(2 * rxError * 1000000UL, tSymbol ), minRxSymbols); - *windowOffset = DIVC((int32_t)(4 * tSymbol - ((*windowTimeout * tSymbol) >> 1)), 1000000L) - 1 - wakeUpTime; + *windowTimeoutInSymbols = MAX( DIV_CEIL( ( ( 2 * minRxSymbols - 8 ) * tSymbolInUs + 2 * ( rxErrorInMs * 1000 ) ), tSymbolInUs ), minRxSymbols ); // Computed number of symbols + *windowOffsetInMs = ( int32_t )DIV_CEIL( ( int32_t )( 4 * tSymbolInUs ) - + ( int32_t )DIV_CEIL( ( *windowTimeoutInSymbols * tSymbolInUs ), 2 ) - + ( int32_t )( wakeUpTimeInMs * 1000 ), 1000 ); } -/* ST_WORKAROUND_END */ int8_t RegionCommonComputeTxPower( int8_t txPowerIndex, float maxEirp, float antennaGain ) { @@ -463,8 +551,9 @@ void RegionCommonRxBeaconSetup( RegionCommonRxBeaconSetupParams_t* rxBeaconSetup 1, 0, 10, rxBeaconSetupParams->SymbolTimeout, true, rxBeaconSetupParams->BeaconSize, false, 0, 0, false, rxContinuous ); Radio.Rx( rxBeaconSetupParams->RxTime ); - + /* ST_WORKAROUND_BEGIN: Print Beacon parameters */ MW_LOG(TS_ON, VLEVEL_M, "RX_BC on freq %d Hz at DR %d\r\n", rxBeaconSetupParams->Frequency, rxBeaconSetupParams->BeaconDatarate ); + /* ST_WORKAROUND_END */ } void RegionCommonCountNbOfEnabledChannels( RegionCommonCountNbOfEnabledChannelsParams_t* countNbOfEnabledChannelsParams, @@ -484,9 +573,9 @@ void RegionCommonCountNbOfEnabledChannels( RegionCommonCountNbOfEnabledChannelsP continue; } if( ( countNbOfEnabledChannelsParams->Joined == false ) && - ( countNbOfEnabledChannelsParams->JoinChannels > 0 ) ) + ( countNbOfEnabledChannelsParams->JoinChannels != NULL ) ) { - if( ( countNbOfEnabledChannelsParams->JoinChannels & ( 1 << j ) ) == 0 ) + if( ( countNbOfEnabledChannelsParams->JoinChannels[k] & ( 1 << j ) ) == 0 ) { continue; } @@ -554,6 +643,47 @@ LoRaMacStatus_t RegionCommonIdentifyChannels( RegionCommonIdentifyChannelsParam_ } } +int8_t RegionCommonGetNextLowerTxDr( RegionCommonGetNextLowerTxDrParams_t *params ) +{ + int8_t drLocal = params->CurrentDr; + + if( params->CurrentDr == params->MinDr ) + { + return params->MinDr; + } + else + { + do + { + drLocal = ( drLocal - 1 ); + } while( ( drLocal != params->MinDr ) && + ( RegionCommonChanVerifyDr( params->NbChannels, params->ChannelsMask, drLocal, params->MinDr, params->MaxDr, params->Channels ) == false ) ); + + return drLocal; + } +} + +int8_t RegionCommonLimitTxPower( int8_t txPower, int8_t maxBandTxPower ) +{ + // Limit tx power to the band max + return MAX( txPower, maxBandTxPower ); +} + +uint32_t RegionCommonGetBandwidth( uint32_t drIndex, const uint32_t* bandwidths ) +{ + switch( bandwidths[drIndex] ) + { + default: + case 125000: + return 0; + case 250000: + return 1; + case 500000: + return 2; + } +} + +/* ST_WORKAROUND_BEGIN: Print Tx/Rx config */ void RegionCommonRxConfigPrint(LoRaMacRxSlot_t rxSlot, uint32_t frequency, int8_t dr) { const char *slotStrings[] = { "1", "2", "C", "Multi_C", "P", "Multi_P" }; @@ -572,3 +702,4 @@ void RegionCommonTxConfigPrint(uint32_t frequency, int8_t dr) { MW_LOG(TS_ON, VLEVEL_M, "TX on freq %d Hz at DR %d\r\n", frequency, dr ); } +/* ST_WORKAROUND_END */ diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.h index 9839a344..23b0d216 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionCommon.h @@ -34,6 +34,16 @@ * Region independent implementations which are common to all regions. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionCommon.h + * @author MCD Application Team + * @brief Region independent implementations which are common to all regions. + ****************************************************************************** + */ #ifndef __REGIONCOMMON_H__ #define __REGIONCOMMON_H__ @@ -46,6 +56,64 @@ extern "C" #include "LoRaMacHeaderTypes.h" #include "Region.h" +// Constants that are common to all the regions. + +/*! + * Receive delay of 1 second. + */ +#define REGION_COMMON_DEFAULT_RECEIVE_DELAY1 1000 + +/*! + * Receive delay of 2 seconds. + */ +#define REGION_COMMON_DEFAULT_RECEIVE_DELAY2 ( REGION_COMMON_DEFAULT_RECEIVE_DELAY1 + 1000 ) + +/*! + * Join accept delay of 5 seconds. + */ +#define REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1 5000 + +/*! + * Join accept delay of 6 seconds. + */ +#define REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2 ( REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1 + 1000 ) + +/*! + * ADR ack limit. + */ +#define REGION_COMMON_DEFAULT_ADR_ACK_LIMIT 64 + +/*! + * ADR ack delay. + */ +#define REGION_COMMON_DEFAULT_ADR_ACK_DELAY 32 + +/*! + * Maximum frame counter gap + */ +#define REGION_COMMON_DEFAULT_MAX_FCNT_GAP 16384 + +/*! + * Retransmission timeout for ACK in milliseconds. + */ +#define REGION_COMMON_DEFAULT_ACK_TIMEOUT 2000 + +/*! + * Rounding limit for generating random retransmission timeout for ACK. + * In milliseconds. + */ +#define REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND 1000 + +/*! + * Default Rx1 receive datarate offset + */ +#define REGION_COMMON_DEFAULT_RX1_DR_OFFSET 0 + +/*! + * Default downlink dwell time configuration + */ +#define REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME 0 + /*! * Default ping slots periodicity * @@ -205,9 +273,11 @@ typedef struct sRegionCommonCountNbOfEnabledChannelsParams */ uint16_t MaxNbChannels; /*! - * A bitmask containing the join channels. + * A pointer to the bitmask containing the + * join channels. Shall have the same dimension as the + * ChannelsMask with a number of MaxNbChannels channels. */ - uint16_t JoinChannels; + uint16_t* JoinChannels; }RegionCommonCountNbOfEnabledChannelsParams_t; typedef struct sRegionCommonIdentifyChannelsParam @@ -262,15 +332,15 @@ typedef struct sRegionCommonSetDutyCycleParams Band_t* Bands; }RegionCommonSetDutyCycleParams_t; -/*! - * \brief Calculates the join duty cycle. - * This is a generic function and valid for all regions. - * - * \param [IN] elapsedTime Elapsed time since the start of the device. - * - * \retval Duty cycle restriction. - */ -uint16_t RegionCommonGetJoinDc( SysTime_t elapsedTime ); +typedef struct sRegionCommonGetNextLowerTxDrParams +{ + int8_t CurrentDr; + int8_t MaxDr; + int8_t MinDr; + uint8_t NbChannels; + uint16_t* ChannelsMask; + ChannelParams_t* Channels; +}RegionCommonGetNextLowerTxDrParams_t; /*! * \brief Verifies, if a value is in a given range. @@ -423,38 +493,36 @@ uint8_t RegionCommonLinkAdrReqVerifyParams( RegionCommonLinkAdrReqVerifyParams_t * * \param [IN] bandwidth Bandwidth to use. * - * \retval Returns the symbol time in us. + * \retval Returns the symbol time in microseconds. */ -uint32_t RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidth ); +uint32_t RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidthInHz ); /*! * \brief Computes the symbol time for FSK modulation. * * \param [IN] phyDr Physical datarate to use. * - * \param [IN] bandwidth Bandwidth to use. - * - * \retval Returns the symbol time in us. + * \retval Returns the symbol time in microseconds. */ -uint32_t RegionCommonComputeSymbolTimeFsk( uint8_t phyDr ); +uint32_t RegionCommonComputeSymbolTimeFsk( uint8_t phyDrInKbps ); /*! * \brief Computes the RX window timeout and the RX window offset. * - * \param [IN] tSymbol Symbol timeout. + * \param [IN] tSymbolInUs Symbol timeout. * * \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. * - * \param [IN] rxError System maximum timing error of the receiver. In milliseconds - * The receiver will turn on in a [-rxError : +rxError] ms interval around RxOffset. + * \param [IN] rxErrorInMs System maximum timing error of the receiver. In milliseconds + * The receiver will turn on in a [-rxErrorInMs : +rxErrorInMs] ms interval around RxOffset. * - * \param [IN] wakeUpTime Wakeup time of the system. + * \param [IN] wakeUpTimeInMs Wakeup time of the system. * - * \param [OUT] windowTimeout RX window timeout. + * \param [OUT] windowTimeoutInSymbols RX window timeout. * - * \param [OUT] windowOffset RX window time offset to be applied to the RX delay. + * \param [OUT] windowOffsetInMs RX window time offset to be applied to the RX delay. */ -void RegionCommonComputeRxWindowParameters( uint32_t tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset ); +void RegionCommonComputeRxWindowParameters( uint32_t tSymbolInUs, uint8_t minRxSymbols, uint32_t rxErrorInMs, uint32_t wakeUpTimeInMs, uint32_t* windowTimeoutInSymbols, int32_t* windowOffsetInMs ); /*! * \brief Computes the txPower, based on the max EIRP and the antenna gain. @@ -522,6 +590,38 @@ LoRaMacStatus_t RegionCommonIdentifyChannels( RegionCommonIdentifyChannelsParam_ uint8_t* nbEnabledChannels, uint8_t* nbRestrictedChannels, TimerTime_t* nextTxDelay ); +/*! + * \brief Selects the next lower datarate. + * + * \param [IN] params Data structure providing parameters based on \ref RegionCommonGetNextLowerTxDrParams_t + * + * \retval The next lower datarate. + */ +int8_t RegionCommonGetNextLowerTxDr( RegionCommonGetNextLowerTxDrParams_t *params ); + +/*! + * \brief Limits the TX power. + * + * \param [IN] txPower Current TX power. + * + * \param [IN] maxBandTxPower Maximum possible TX power. + * + * \retval Limited TX power. + */ +int8_t RegionCommonLimitTxPower( int8_t txPower, int8_t maxBandTxPower ); + +/*! + * \brief Gets the bandwidth. + * + * \param [IN] drIndex Datarate index. + * + * \param [IN] bandwidths A pointer to the bandwidth table. + * + * \retval Bandwidth. + */ +uint32_t RegionCommonGetBandwidth( uint32_t drIndex, const uint32_t* bandwidths ); + +/* ST_WORKAROUND_BEGIN: Print Tx/Rx config */ /*! * \brief Print the current RX configuration * @@ -545,7 +645,7 @@ void RegionCommonRxConfigPrint(LoRaMacRxSlot_t rxSlot, * */ void RegionCommonTxConfigPrint(uint32_t frequency, int8_t dr); - +/* ST_WORKAROUND_END */ /*! \} defgroup REGIONCOMMON */ #ifdef __cplusplus diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.c index 4b743439..77e9b05e 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.c @@ -28,82 +28,32 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionEU433.c + * @author MCD Application Team + * @brief Region implementation for EU433 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionEU433.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionEU433NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ EU433_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ EU433_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionEU433NvmCtx_t; - +#if defined( REGION_EU433 ) /* * Non-volatile module context. */ -static RegionEU433NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsEU433[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - static bool VerifyRfFreq( uint32_t freq ) { // Check radio driver support @@ -122,7 +72,7 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesEU433[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsEU433 ); TimerTime_t timeOnAir = 0; if( datarate == DR_7 ) @@ -135,11 +85,13 @@ static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) } return timeOnAir; } +#endif /* REGION_EU433 */ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_EU433 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -159,7 +111,16 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, EU433_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )EU433_TX_MAX_DATARATE, + .MinDr = ( int8_t )EU433_TX_MIN_DATARATE, + .NbChannels = EU433_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -174,12 +135,12 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = EU433_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = EU433_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -187,11 +148,13 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateEU433[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterEU433[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = EU433_DUTY_CYCLE_ENABLED; @@ -204,37 +167,37 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = EU433_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = EU433_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = EU433_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = EU433_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = EU433_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( EU433_ACKTIMEOUT + randr( -EU433_ACK_TIMEOUT_RND, EU433_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = EU433_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -249,12 +212,12 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -264,13 +227,17 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = EU433_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -317,7 +284,7 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsEU433 ); break; } default: @@ -326,17 +293,21 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_EU433 */ return phyParam; } void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_EU433 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_EU433 */ } void RegionEU433InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_EU433 ) Band_t bands[EU433_MAX_NB_BANDS] = { EU433_BAND0 @@ -346,43 +317,43 @@ void RegionEU433InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU433_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU433_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) EU433_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) EU433_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) EU433_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) EU433_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) EU433_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) EU433_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -390,16 +361,12 @@ void RegionEU433InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionEU433GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionEU433NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_EU433 */ } bool RegionEU433Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_EU433 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -431,10 +398,14 @@ bool RegionEU433Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_EU433 */ } void RegionEU433ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_EU433 ) ChannelParams_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; @@ -490,52 +461,58 @@ void RegionEU433ApplyCFList( ApplyCFListParams_t* applyCFList ) RegionEU433ChannelsRemove( &channelRemove ); } } +#endif /* REGION_EU433 */ } bool RegionEU433ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_EU433 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_EU433 */ } void RegionEU433ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_EU433 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, EU433_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsEU433 ); if( rxConfigParams->Datarate == DR_7 ) { // FSK - tSymbol = RegionCommonComputeSymbolTimeFsk( DataratesEU433[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeFsk( DataratesEU433[rxConfigParams->Datarate] ); } else { // LoRa - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesEU433[rxConfigParams->Datarate], BandwidthsEU433[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesEU433[rxConfigParams->Datarate], BandwidthsEU433[rxConfigParams->Datarate] ); } - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_EU433 */ } bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_EU433 ) RadioModems_t modem; int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; @@ -550,11 +527,11 @@ bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -575,6 +552,7 @@ bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterEU433[dr]; @@ -584,27 +562,33 @@ bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) maxPayload = MaxPayloadOfDatarateEU433[dr]; } Radio.SetMaxPayloadLength( modem, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_EU433 */ } bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_EU433 ) RadioModems_t modem; int8_t phyDr = DataratesEU433[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsEU433 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -617,7 +601,7 @@ bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); } /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Update time-on-air @@ -628,11 +612,15 @@ bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_EU433 */ } uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_EU433 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -675,7 +663,7 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -683,7 +671,7 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -692,7 +680,7 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in } } - // Get the minimum possible datarate + // Get the minimum possible datarate getPhy.Attribute = PHY_MIN_TX_DR; getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; phyParam = RegionEU433GetPhyParam( &getPhy ); @@ -709,7 +697,7 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = EU433_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = EU433_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = EU433_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -721,9 +709,9 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -732,12 +720,14 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_EU433 */ return status; } uint8_t RegionEU433RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_EU433 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -757,10 +747,11 @@ uint8_t RegionEU433RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_EU433 */ return status; } -uint8_t RegionEU433NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionEU433NewChannelReq( NewChannelReqParams_t* newChannelReq ) { uint8_t status = 0x03; ChannelAddParams_t channelAdd; @@ -815,12 +806,14 @@ uint8_t RegionEU433NewChannelReq( NewChannelReqParams_t* newChannelReq ) int8_t RegionEU433TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { uint8_t status = 0x03; +#if defined( REGION_EU433 ) // Verify if the frequency is supported if( VerifyRfFreq( dlChannelReq->Rx1Frequency ) == false ) @@ -829,7 +822,7 @@ uint8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -837,39 +830,46 @@ uint8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } +#endif /* REGION_EU433 */ return status; } int8_t RegionEU433AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_EU433 ) return currentDr; +#else + return -1; +#endif /* REGION_EU433 */ } LoRaMacStatus_t RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_EU433 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[EU433_MAX_NB_CHANNELS] = { 0 }; RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; + uint16_t joinChannels = EU433_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = EU433_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = EU433_JOIN_CHANNELS; + countChannelsParams.JoinChannels = &joinChannels; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -893,13 +893,17 @@ LoRaMacStatus_t RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_EU433 */ } LoRaMacStatus_t RegionEU433ChannelAdd( ChannelAddParams_t* channelAdd ) { +#if defined( REGION_EU433 ) bool drInvalid = false; bool freqInvalid = false; uint8_t id = channelAdd->ChannelId; @@ -951,14 +955,18 @@ LoRaMacStatus_t RegionEU433ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_EU433 */ } bool RegionEU433ChannelsRemove( ChannelRemoveParams_t* channelRemove ) { +#if defined( REGION_EU433 ) uint8_t id = channelRemove->ChannelId; if( id < EU433_NUMB_DEFAULT_CHANNELS ) @@ -967,25 +975,31 @@ bool RegionEU433ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, EU433_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, EU433_MAX_NB_CHANNELS ); +#else + return false; +#endif /* REGION_EU433 */ } void RegionEU433SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_EU433 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_EU433 */ } uint8_t RegionEU433ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_EU433 ) int8_t datarate = dr - drOffset; if( datarate < 0 ) @@ -993,10 +1007,14 @@ uint8_t RegionEU433ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d datarate = DR_0; } return datarate; +#else + return 0; +#endif /* REGION_EU433 */ } void RegionEU433RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_EU433 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesEU433; @@ -1004,11 +1022,12 @@ void RegionEU433RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) regionCommonRxBeaconSetup.BeaconSize = EU433_BEACON_SIZE; regionCommonRxBeaconSetup.BeaconDatarate = EU433_BEACON_CHANNEL_DR; regionCommonRxBeaconSetup.BeaconChannelBW = EU433_BEACON_CHANNEL_BW; - regionCommonRxBeaconSetup.RxTime = rxBeaconSetup->RxTime; + regionCommonRxBeaconSetup.RxTime = rxBeaconSetup->RxTime; regionCommonRxBeaconSetup.SymbolTimeout = rxBeaconSetup->SymbolTimeout; RegionCommonRxBeaconSetup( ®ionCommonRxBeaconSetup ); // Store downlink datarate *outDr = EU433_BEACON_CHANNEL_DR; +#endif /* REGION_EU433 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.h index ec0b6014..c77a22b2 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU433.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionEU433.h + * @author MCD Application Team + * @brief Region definition for EU433 + ****************************************************************************** + */ #ifndef __REGION_EU433_H__ #define __REGION_EU433_H__ @@ -94,11 +104,6 @@ extern "C" */ #define EU433_MAX_RX1_DR_OFFSET 5 -/*! - * Default Rx1 receive datarate offset - */ -#define EU433_DEFAULT_RX1_DR_OFFSET 0 - /*! * Minimal Tx output power that can be used by the node */ @@ -124,16 +129,6 @@ extern "C" */ #define EU433_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define EU433_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define EU433_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -144,41 +139,6 @@ extern "C" */ #define EU433_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define EU433_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define EU433_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define EU433_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define EU433_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define EU433_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define EU433_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define EU433_ACK_TIMEOUT_RND 1000 - /*! * Verification of default datarate */ @@ -201,6 +161,11 @@ extern "C" */ #define EU433_MAX_NB_BANDS 1 +/*! + * Default uplink dwell time configuration + */ +#define EU433_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -246,9 +211,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 % +#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -283,6 +248,7 @@ static const uint8_t DataratesEU433[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; */ static const uint32_t BandwidthsEU433[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ @@ -292,6 +258,7 @@ static const uint8_t MaxPayloadOfDatarateEU433[] = { 51, 51, 51, 115, 242, 242, * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterEU433[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -316,15 +283,6 @@ void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionEU433InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionEU433GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -417,7 +375,7 @@ uint8_t RegionEU433RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionEU433NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionEU433NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -437,7 +395,7 @@ int8_t RegionEU433TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.c index 9ca1d975..8db7ea22 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.c @@ -28,82 +28,32 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionEU868.c + * @author MCD Application Team + * @brief Region implementation for EU868 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionEU868.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionEU868NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ EU868_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ EU868_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionEU868NvmCtx_t; - +#if defined( REGION_EU868 ) /* * Non-volatile module context. */ -static RegionEU868NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsEU868[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - static bool VerifyRfFreq( uint32_t freq, uint8_t *band ) { // Check radio driver support @@ -147,7 +97,7 @@ static bool VerifyRfFreq( uint32_t freq, uint8_t *band ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesEU868[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsEU868 ); TimerTime_t timeOnAir = 0; if( datarate == DR_7 ) @@ -160,11 +110,13 @@ static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) } return timeOnAir; } +#endif /* REGION_EU868 */ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_EU868 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -184,7 +136,16 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, EU868_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )EU868_TX_MAX_DATARATE, + .MinDr = ( int8_t )EU868_TX_MIN_DATARATE, + .NbChannels = EU868_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -199,12 +160,12 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = EU868_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = EU868_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -212,11 +173,13 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateEU868[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterEU868[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = EU868_DUTY_CYCLE_ENABLED; @@ -229,37 +192,37 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = EU868_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = EU868_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = EU868_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = EU868_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = EU868_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( EU868_ACKTIMEOUT + randr( -EU868_ACK_TIMEOUT_RND, EU868_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = EU868_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -274,12 +237,12 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -289,13 +252,17 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = EU868_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -342,7 +309,7 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsEU868 ); break; } default: @@ -351,17 +318,21 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_EU868 */ return phyParam; } void RegionEU868SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_EU868 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_EU868 */ } void RegionEU868InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_EU868 ) Band_t bands[EU868_MAX_NB_BANDS] = { EU868_BAND0, @@ -376,43 +347,43 @@ void RegionEU868InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU868_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU868_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) EU868_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) EU868_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) EU868_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) EU868_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) EU868_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) EU868_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -420,16 +391,12 @@ void RegionEU868InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionEU868GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionEU868NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_EU868 */ } bool RegionEU868Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_EU868 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -462,10 +429,14 @@ bool RegionEU868Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_EU868 */ } void RegionEU868ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_EU868 ) ChannelParams_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; @@ -521,52 +492,58 @@ void RegionEU868ApplyCFList( ApplyCFListParams_t* applyCFList ) RegionEU868ChannelsRemove( &channelRemove ); } } +#endif /* REGION_EU868 */ } bool RegionEU868ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_EU868 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_EU868 */ } void RegionEU868ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_EU868 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, EU868_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsEU868 ); if( rxConfigParams->Datarate == DR_7 ) { // FSK - tSymbol = RegionCommonComputeSymbolTimeFsk( DataratesEU868[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeFsk( DataratesEU868[rxConfigParams->Datarate] ); } else { // LoRa - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesEU868[rxConfigParams->Datarate], BandwidthsEU868[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesEU868[rxConfigParams->Datarate], BandwidthsEU868[rxConfigParams->Datarate] ); } - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_EU868 */ } bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_EU868 ) RadioModems_t modem; int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; @@ -581,11 +558,11 @@ bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -606,6 +583,7 @@ bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterEU868[dr]; @@ -616,27 +594,33 @@ bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) } Radio.SetMaxPayloadLength( modem, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_EU868 */ } bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_EU868 ) RadioModems_t modem; int8_t phyDr = DataratesEU868[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsEU868 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -649,7 +633,7 @@ bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); } /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Update time-on-air @@ -660,11 +644,15 @@ bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_EU868 */ } uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_EU868 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -707,7 +695,7 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -715,7 +703,7 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -741,7 +729,7 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = EU868_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = EU868_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = EU868_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -753,9 +741,9 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -764,12 +752,14 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_EU868 */ return status; } uint8_t RegionEU868RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_EU868 ) uint8_t band = 0; // Verify radio frequency @@ -790,10 +780,11 @@ uint8_t RegionEU868RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_EU868 */ return status; } -uint8_t RegionEU868NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionEU868NewChannelReq( NewChannelReqParams_t* newChannelReq ) { uint8_t status = 0x03; ChannelAddParams_t channelAdd; @@ -848,12 +839,14 @@ uint8_t RegionEU868NewChannelReq( NewChannelReqParams_t* newChannelReq ) int8_t RegionEU868TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { uint8_t status = 0x03; +#if defined( REGION_EU868 ) uint8_t band = 0; // Verify if the frequency is supported @@ -863,7 +856,7 @@ uint8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -871,39 +864,46 @@ uint8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } +#endif /* REGION_EU868 */ return status; } int8_t RegionEU868AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_EU868 ) return currentDr; +#else + return -1; +#endif /* REGION_EU868 */ } LoRaMacStatus_t RegionEU868NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_EU868 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[EU868_MAX_NB_CHANNELS] = { 0 }; RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; + uint16_t joinChannels = EU868_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = EU868_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = EU868_JOIN_CHANNELS; + countChannelsParams.JoinChannels = &joinChannels; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -927,13 +927,17 @@ LoRaMacStatus_t RegionEU868NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_EU868 */ } LoRaMacStatus_t RegionEU868ChannelAdd( ChannelAddParams_t* channelAdd ) { +#if defined( REGION_EU868 ) uint8_t band = 0; bool drInvalid = false; bool freqInvalid = false; @@ -986,14 +990,18 @@ LoRaMacStatus_t RegionEU868ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = band; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = band; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_EU868 */ } bool RegionEU868ChannelsRemove( ChannelRemoveParams_t* channelRemove ) { +#if defined( REGION_EU868 ) uint8_t id = channelRemove->ChannelId; if( id < EU868_NUMB_DEFAULT_CHANNELS ) @@ -1002,25 +1010,31 @@ bool RegionEU868ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, EU868_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, EU868_MAX_NB_CHANNELS ); +#else + return false; +#endif /* REGION_EU868 */ } void RegionEU868SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_EU868 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_EU868 */ } uint8_t RegionEU868ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_EU868 ) int8_t datarate = dr - drOffset; if( datarate < 0 ) @@ -1028,10 +1042,14 @@ uint8_t RegionEU868ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d datarate = DR_0; } return datarate; +#else + return 0; +#endif /* REGION_EU868 */ } void RegionEU868RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_EU868 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesEU868; @@ -1046,4 +1064,5 @@ void RegionEU868RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = EU868_BEACON_CHANNEL_DR; +#endif /* REGION_EU868 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.h index a154ac6e..9e760530 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionEU868.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionEU868.h + * @author MCD Application Team + * @brief Region definition for EU868 + ****************************************************************************** + */ #ifndef __REGION_EU868_H__ #define __REGION_EU868_H__ @@ -94,11 +104,6 @@ extern "C" */ #define EU868_MAX_RX1_DR_OFFSET 5 -/*! - * Default Rx1 receive datarate offset - */ -#define EU868_DEFAULT_RX1_DR_OFFSET 0 - /*! * Minimal Tx output power that can be used by the node */ @@ -124,16 +129,6 @@ extern "C" */ #define EU868_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define EU868_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define EU868_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -144,41 +139,6 @@ extern "C" */ #define EU868_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define EU868_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define EU868_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define EU868_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define EU868_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define EU868_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define EU868_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define EU868_ACK_TIMEOUT_RND 1000 - #if ( EU868_DEFAULT_DATARATE > DR_5 ) #error "A default DR higher than DR_5 may lead to connectivity loss." #endif @@ -193,6 +153,11 @@ extern "C" */ #define EU868_RX_WND_2_DR DR_0 +/*! + * Default uplink dwell time configuration + */ +#define EU868_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -243,40 +208,40 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 % +#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 1.0 % /*! * Band 1 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 % +#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 1.0 % /*! * Band 2 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 0.1 % +#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 0.1 % /*! * Band 3 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 10.0 % +#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 10.0 % /*! * Band 4 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 % +#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 1.0 % /*! * Band 5 definition * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff, * DutyCycleTimePeriod, MaxAllowedTimeOnAir, AggregatedTimeOnAir, StartTimeOfPeriod } */ -#define EU868_BAND5 { 1000, EU868_MAX_TX_POWER, 0, 0, 0, 0 } // 0.1 % +#define EU868_BAND5 { 1000, EU868_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 0.1 % /*! * LoRaMac default channel 1 @@ -311,6 +276,7 @@ static const uint8_t DataratesEU868[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; */ static const uint32_t BandwidthsEU868[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ @@ -320,6 +286,7 @@ static const uint8_t MaxPayloadOfDatarateEU868[] = { 51, 51, 51, 115, 242, 242, * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterEU868[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -344,15 +311,6 @@ void RegionEU868SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionEU868InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionEU868GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -445,7 +403,7 @@ uint8_t RegionEU868RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionEU868NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionEU868NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -465,7 +423,7 @@ int8_t RegionEU868TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.c index 62b68655..6d033b33 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.c @@ -28,85 +28,31 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionIN865.c + * @author MCD Application Team + * @brief Region implementation for IN865 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionIN865.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionIN865NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ IN865_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ IN865_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionIN865NvmCtx_t; - +#if defined( REGION_IN865 ) /* * Non-volatile module context. */ -static RegionIN865NvmCtx_t NvmCtx; - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else if( dr == DR_7 ) - { - nextLowerDr = DR_5; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsIN865[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; - return txPowerResult; -} static bool VerifyRfFreq( uint32_t freq ) { @@ -126,7 +72,7 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesIN865[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsIN865 ); TimerTime_t timeOnAir = 0; if( datarate == DR_7 ) @@ -139,11 +85,13 @@ static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) } return timeOnAir; } +#endif /* REGION_IN865 */ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_IN865 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -163,7 +111,16 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, IN865_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )IN865_TX_MAX_DATARATE, + .MinDr = ( int8_t )IN865_TX_MIN_DATARATE, + .NbChannels = IN865_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -178,12 +135,12 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = IN865_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = IN865_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -191,11 +148,13 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateIN865[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterIN865[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = IN865_DUTY_CYCLE_ENABLED; @@ -208,37 +167,37 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = IN865_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = IN865_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = IN865_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = IN865_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = IN865_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( IN865_ACKTIMEOUT + randr( -IN865_ACK_TIMEOUT_RND, IN865_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = IN865_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -253,12 +212,12 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -268,13 +227,17 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = IN865_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -321,7 +284,7 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsIN865 ); break; } default: @@ -330,17 +293,21 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_IN865 */ return phyParam; } void RegionIN865SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_IN865 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_IN865 */ } void RegionIN865InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_IN865 ) Band_t bands[IN865_MAX_NB_BANDS] = { IN865_BAND0 @@ -350,43 +317,43 @@ void RegionIN865InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Initialize bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * IN865_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * IN865_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) IN865_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) IN865_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) IN865_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) IN865_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) IN865_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) IN865_LC3; // Initialize the channels default mask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Default ChannelsMask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Default ChannelsMask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -394,16 +361,12 @@ void RegionIN865InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionIN865GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionIN865NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_IN865 */ } bool RegionIN865Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_IN865 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -449,10 +412,14 @@ bool RegionIN865Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_IN865 */ } void RegionIN865ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_IN865 ) ChannelParams_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; @@ -508,52 +475,58 @@ void RegionIN865ApplyCFList( ApplyCFListParams_t* applyCFList ) RegionIN865ChannelsRemove( &channelRemove ); } } +#endif /* REGION_IN865 */ } bool RegionIN865ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_IN865 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_IN865 */ } void RegionIN865ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_IN865 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, IN865_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsIN865 ); if( rxConfigParams->Datarate == DR_7 ) { // FSK - tSymbol = RegionCommonComputeSymbolTimeFsk( DataratesIN865[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeFsk( DataratesIN865[rxConfigParams->Datarate] ); } else { // LoRa - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesIN865[rxConfigParams->Datarate], BandwidthsIN865[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesIN865[rxConfigParams->Datarate], BandwidthsIN865[rxConfigParams->Datarate] ); } - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_IN865 */ } bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_IN865 ) RadioModems_t modem; int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; @@ -568,11 +541,11 @@ bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -593,6 +566,7 @@ bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterIN865[dr]; @@ -602,27 +576,33 @@ bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) maxPayload = MaxPayloadOfDatarateIN865[dr]; } Radio.SetMaxPayloadLength( modem, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_IN865 */ } bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_IN865 ) RadioModems_t modem; int8_t phyDr = DataratesIN865[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsIN865 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -635,7 +615,7 @@ bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); } /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Update time-on-air @@ -646,11 +626,15 @@ bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_IN865 */ } uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_IN865 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -693,7 +677,7 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -701,7 +685,7 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -729,7 +713,7 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = IN865_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = IN865_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = IN865_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -746,9 +730,9 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -757,12 +741,14 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_IN865 */ return status; } uint8_t RegionIN865RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_IN865 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -771,7 +757,9 @@ uint8_t RegionIN865RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) } // Verify datarate - if( RegionCommonValueInRange( rxParamSetupReq->Datarate, IN865_RX_MIN_DATARATE, IN865_RX_MAX_DATARATE ) == false ) + if( ( RegionCommonValueInRange( rxParamSetupReq->Datarate, IN865_RX_MIN_DATARATE, IN865_RX_MAX_DATARATE ) == false ) || + // DR_6 is not supported by this region + ( rxParamSetupReq->Datarate == DR_6 ) ) { status &= 0xFD; // Datarate KO } @@ -782,10 +770,11 @@ uint8_t RegionIN865RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_IN865 */ return status; } -uint8_t RegionIN865NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionIN865NewChannelReq( NewChannelReqParams_t* newChannelReq ) { uint8_t status = 0x03; ChannelAddParams_t channelAdd; @@ -840,12 +829,14 @@ uint8_t RegionIN865NewChannelReq( NewChannelReqParams_t* newChannelReq ) int8_t RegionIN865TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { uint8_t status = 0x03; +#if defined( REGION_IN865 ) // Verify if the frequency is supported if( VerifyRfFreq( dlChannelReq->Rx1Frequency ) == false ) @@ -854,7 +845,7 @@ uint8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -862,39 +853,46 @@ uint8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } +#endif /* REGION_IN865 */ return status; } int8_t RegionIN865AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_IN865 ) return currentDr; +#else + return -1; +#endif /* REGION_IN865 */ } LoRaMacStatus_t RegionIN865NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_IN865 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[IN865_MAX_NB_CHANNELS] = { 0 }; RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; + uint16_t joinChannels = IN865_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = IN865_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = IN865_JOIN_CHANNELS; + countChannelsParams.JoinChannels = &joinChannels; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -918,13 +916,17 @@ LoRaMacStatus_t RegionIN865NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_IN865 */ } LoRaMacStatus_t RegionIN865ChannelAdd( ChannelAddParams_t* channelAdd ) { +#if defined( REGION_IN865 ) bool drInvalid = false; bool freqInvalid = false; uint8_t id = channelAdd->ChannelId; @@ -976,14 +978,18 @@ LoRaMacStatus_t RegionIN865ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_IN865 */ } bool RegionIN865ChannelsRemove( ChannelRemoveParams_t* channelRemove ) { +#if defined( REGION_IN865 ) uint8_t id = channelRemove->ChannelId; if( id < IN865_NUMB_DEFAULT_CHANNELS ) @@ -992,31 +998,41 @@ bool RegionIN865ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, IN865_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, IN865_MAX_NB_CHANNELS ); +#else + return false; +#endif /* REGION_IN865 */ } void RegionIN865SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_IN865 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_IN865 */ } uint8_t RegionIN865ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_IN865 ) // Apply offset formula return MIN( DR_5, MAX( DR_0, dr - EffectiveRx1DrOffsetIN865[drOffset] ) ); +#else + return 0; +#endif /* REGION_IN865 */ } void RegionIN865RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_IN865 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesIN865; @@ -1031,4 +1047,5 @@ void RegionIN865RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = IN865_BEACON_CHANNEL_DR; +#endif /* REGION_IN865 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.h index 48af152f..1fdec3bb 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionIN865.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionIN865.h + * @author MCD Application Team + * @brief Region definition for IN865 + ****************************************************************************** + */ #ifndef __REGION_IN865_H__ #define __REGION_IN865_H__ @@ -94,11 +104,6 @@ extern "C" */ #define IN865_MAX_RX1_DR_OFFSET 7 -/*! - * Default Rx1 receive datarate offset - */ -#define IN865_DEFAULT_RX1_DR_OFFSET 0 - /*! * Minimal Tx output power that can be used by the node */ @@ -124,16 +129,6 @@ extern "C" */ #define IN865_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define IN865_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define IN865_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -144,41 +139,6 @@ extern "C" */ #define IN865_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define IN865_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define IN865_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define IN865_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define IN865_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define IN865_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define IN865_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define IN865_ACK_TIMEOUT_RND 1000 - #if ( IN865_DEFAULT_DATARATE > DR_5 ) #error "A default DR higher than DR_5 may lead to connectivity loss." #endif @@ -193,6 +153,11 @@ extern "C" */ #define IN865_RX_WND_2_DR DR_2 +/*! + * Default uplink dwell time configuration + */ +#define IN865_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -243,9 +208,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 % +#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 100.0 % /*! * LoRaMac default channel 1 @@ -280,6 +245,7 @@ static const uint8_t DataratesIN865[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; */ static const uint32_t BandwidthsIN865[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ @@ -289,6 +255,7 @@ static const uint8_t MaxPayloadOfDatarateIN865[] = { 51, 51, 51, 115, 242, 242, * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterIN865[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * Effective datarate offsets for receive window 1. @@ -318,15 +285,6 @@ void RegionIN865SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionIN865InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionIN865GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -419,7 +377,7 @@ uint8_t RegionIN865RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionIN865NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionIN865NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -439,7 +397,7 @@ int8_t RegionIN865TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.c index 3f4c6b05..bbdc672e 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.c @@ -28,10 +28,20 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionKR920.c + * @author MCD Application Team + * @brief Region implementation for KR920 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionKR920.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 1 @@ -42,50 +52,14 @@ */ #define KR920_LBT_RX_BANDWIDTH 200000 -/*! - * Region specific context - */ -typedef struct sRegionKR920NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ KR920_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ KR920_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionKR920NvmCtx_t; - +#if defined( REGION_KR920 ) /* * Non-volatile module context. */ -static RegionKR920NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - static int8_t GetMaxEIRP( uint32_t freq ) { if( freq >= 922100000 ) @@ -96,30 +70,6 @@ static int8_t GetMaxEIRP( uint32_t freq ) return KR920_DEFAULT_MAX_EIRP_LOW; } -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsKR920[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - static bool VerifyRfFreq( uint32_t freq ) { uint32_t tmpFreq = freq; @@ -147,15 +97,17 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesKR920[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsKR920 ); return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true ); } +#endif /* REGION_KR920 */ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_KR920 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -175,7 +127,16 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, KR920_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )KR920_TX_MAX_DATARATE, + .MinDr = ( int8_t )KR920_TX_MIN_DATARATE, + .NbChannels = KR920_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -190,12 +151,12 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = KR920_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = KR920_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -203,11 +164,13 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateKR920[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterKR920[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = KR920_DUTY_CYCLE_ENABLED; @@ -220,37 +183,37 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = KR920_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = KR920_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = KR920_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = KR920_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = KR920_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( KR920_ACKTIMEOUT + randr( -KR920_ACK_TIMEOUT_RND, KR920_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = KR920_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -265,12 +228,12 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -280,13 +243,17 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = KR920_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -337,7 +304,7 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsKR920 ); break; } default: @@ -346,17 +313,21 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_KR920 */ return phyParam; } void RegionKR920SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_KR920 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_KR920 */ } void RegionKR920InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_KR920 ) Band_t bands[KR920_MAX_NB_BANDS] = { KR920_BAND0 @@ -366,43 +337,43 @@ void RegionKR920InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Initialize bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * KR920_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * KR920_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) KR920_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) KR920_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) KR920_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) KR920_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) KR920_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) KR920_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -410,16 +381,12 @@ void RegionKR920InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionKR920GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionKR920NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_KR920 */ } bool RegionKR920Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_KR920 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -451,10 +418,14 @@ bool RegionKR920Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_KR920 */ } void RegionKR920ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_KR920 ) ChannelParams_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; @@ -510,45 +481,51 @@ void RegionKR920ApplyCFList( ApplyCFListParams_t* applyCFList ) RegionKR920ChannelsRemove( &channelRemove ); } } +#endif /* REGION_KR920 */ } bool RegionKR920ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_KR920 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_KR920 */ } void RegionKR920ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_KR920 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, KR920_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsKR920 ); - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesKR920[rxConfigParams->Datarate], BandwidthsKR920[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesKR920[rxConfigParams->Datarate], BandwidthsKR920[rxConfigParams->Datarate] ); - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_KR920 */ } bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_KR920 ) int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; @@ -562,11 +539,11 @@ bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -578,6 +555,7 @@ bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) // Radio configuration Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterKR920[dr]; @@ -588,20 +566,26 @@ bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) } Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_KR920 */ } bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_KR920 ) int8_t phyDr = DataratesKR920[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - float maxEIRP = GetMaxEIRP( NvmCtx.Channels[txConfig->Channel].Frequency ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsKR920 ); + float maxEIRP = GetMaxEIRP( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); int8_t phyTxPower = 0; // Take the minimum between the maxEIRP and txConfig->MaxEirp. @@ -612,11 +596,11 @@ bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, maxEIRP, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Setup maximum payload length of the radio driver @@ -626,11 +610,15 @@ bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_KR920 */ } uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_KR920 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -673,7 +661,7 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -681,7 +669,7 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -707,7 +695,7 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = KR920_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = KR920_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = KR920_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -719,9 +707,9 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -730,12 +718,14 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_KR920 */ return status; } uint8_t RegionKR920RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_KR920 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -755,10 +745,11 @@ uint8_t RegionKR920RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_KR920 */ return status; } -uint8_t RegionKR920NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionKR920NewChannelReq( NewChannelReqParams_t* newChannelReq ) { uint8_t status = 0x03; ChannelAddParams_t channelAdd; @@ -813,12 +804,14 @@ uint8_t RegionKR920NewChannelReq( NewChannelReqParams_t* newChannelReq ) int8_t RegionKR920TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { uint8_t status = 0x03; +#if defined( REGION_KR920 ) // Verify if the frequency is supported if( VerifyRfFreq( dlChannelReq->Rx1Frequency ) == false ) @@ -827,7 +820,7 @@ uint8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -835,19 +828,25 @@ uint8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } +#endif /* REGION_KR920 */ return status; } int8_t RegionKR920AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_KR920 ) return currentDr; +#else + return -1; +#endif /* REGION_KR920 */ } LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_KR920 ) uint8_t channelNext = 0; uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; @@ -855,20 +854,21 @@ LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_ RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; + uint16_t joinChannels = KR920_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = KR920_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = KR920_JOIN_CHANNELS; + countChannelsParams.JoinChannels = &joinChannels; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -893,7 +893,7 @@ LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_ // Perform carrier sense for KR920_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism - if( Radio.IsChannelFree( NvmCtx.Channels[channelNext].Frequency, KR920_LBT_RX_BANDWIDTH, KR920_RSSI_FREE_TH, KR920_CARRIER_SENSE_TIME ) == true ) + if( Radio.IsChannelFree( RegionNvmGroup2->Channels[channelNext].Frequency, KR920_LBT_RX_BANDWIDTH, KR920_RSSI_FREE_TH, KR920_CARRIER_SENSE_TIME ) == true ) { // Free channel found *channel = channelNext; @@ -907,13 +907,17 @@ LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_KR920 */ } LoRaMacStatus_t RegionKR920ChannelAdd( ChannelAddParams_t* channelAdd ) { +#if defined( REGION_KR920 ) bool drInvalid = false; bool freqInvalid = false; uint8_t id = channelAdd->ChannelId; @@ -965,14 +969,18 @@ LoRaMacStatus_t RegionKR920ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_KR920 */ } bool RegionKR920ChannelsRemove( ChannelRemoveParams_t* channelRemove ) { +#if defined( REGION_KR920 ) uint8_t id = channelRemove->ChannelId; if( id < KR920_NUMB_DEFAULT_CHANNELS ) @@ -981,17 +989,21 @@ bool RegionKR920ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, KR920_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, KR920_MAX_NB_CHANNELS ); +#else + return false; +#endif /* REGION_KR920 */ } void RegionKR920SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); - float maxEIRP = GetMaxEIRP( NvmCtx.Channels[continuousWave->Channel].Frequency ); +#if defined( REGION_KR920 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); + float maxEIRP = GetMaxEIRP( RegionNvmGroup2->Channels[continuousWave->Channel].Frequency ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Take the minimum between the maxEIRP and continuousWave->MaxEirp. // The value of continuousWave->MaxEirp could have changed during runtime, e.g. due to a MAC command. @@ -1001,10 +1013,12 @@ void RegionKR920SetContinuousWave( ContinuousWaveParams_t* continuousWave ) phyTxPower = RegionCommonComputeTxPower( txPowerLimited, maxEIRP, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_KR920 */ } uint8_t RegionKR920ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_KR920 ) int8_t datarate = dr - drOffset; if( datarate < 0 ) @@ -1012,10 +1026,14 @@ uint8_t RegionKR920ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d datarate = DR_0; } return datarate; +#else + return 0; +#endif /* REGION_KR920 */ } void RegionKR920RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_KR920 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesKR920; @@ -1030,4 +1048,5 @@ void RegionKR920RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = KR920_BEACON_CHANNEL_DR; +#endif /* REGION_KR920 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.h index 4436daa7..a33c1ee4 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionKR920.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionKR920.h + * @author MCD Application Team + * @brief Region definition for KR920 + ****************************************************************************** + */ #ifndef __REGION_KR920_H__ #define __REGION_KR920_H__ @@ -94,11 +104,6 @@ extern "C" */ #define KR920_MAX_RX1_DR_OFFSET 5 -/*! - * Default Rx1 receive datarate offset - */ -#define KR920_DEFAULT_RX1_DR_OFFSET 0 - /*! * Minimal Tx output power that can be used by the node */ @@ -129,16 +134,6 @@ extern "C" */ #define KR920_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define KR920_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define KR920_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -149,41 +144,6 @@ extern "C" */ #define KR920_MAX_RX_WINDOW 4000 -/*! - * Receive delay 1 - */ -#define KR920_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define KR920_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define KR920_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define KR920_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define KR920_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define KR920_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define KR920_ACK_TIMEOUT_RND 1000 - #if ( KR920_DEFAULT_DATARATE > DR_5 ) #error "A default DR higher than DR_5 may lead to connectivity loss." #endif @@ -198,6 +158,11 @@ extern "C" */ #define KR920_RX_WND_2_DR DR_0 +/*! + * Default uplink dwell time configuration + */ +#define KR920_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -248,9 +213,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 % +#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 100.0 % /*! * LoRaMac default channel 1 @@ -295,6 +260,7 @@ static const uint8_t DataratesKR920[] = { 12, 11, 10, 9, 8, 7 }; */ static const uint32_t BandwidthsKR920[] = { 125000, 125000, 125000, 125000, 125000, 125000 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Can operate with and without a repeater. */ @@ -304,6 +270,7 @@ static const uint8_t MaxPayloadOfDatarateKR920[] = { 51, 51, 51, 115, 242, 242 } * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterKR920[] = { 51, 51, 51, 115, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -328,15 +295,6 @@ void RegionKR920SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionKR920InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionKR920GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -429,7 +387,7 @@ uint8_t RegionKR920RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionKR920NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionKR920NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -449,7 +407,7 @@ int8_t RegionKR920TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionNvm.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionNvm.h new file mode 100644 index 00000000..cc608f47 --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionNvm.h @@ -0,0 +1,135 @@ +/*! + * \file RegionNvm.h + * + * \brief Region independent non-volatile data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \addtogroup REGIONCOMMON + * + * \{ + */ +#ifndef __REGIONNVM_H__ +#define __REGIONNVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "lorawan_conf.h" +#include "LoRaMacTypes.h" + +// Selection of REGION_NVM_MAX_NB_CHANNELS +#if defined( REGION_CN470 ) + #define REGION_NVM_MAX_NB_CHANNELS 96 +#elif defined( REGION_US915 ) || defined( REGION_AU915 ) + #define REGION_NVM_MAX_NB_CHANNELS 72 +#elif defined( REGION_AS923 ) || defined( REGION_CN779 ) || \ + defined( REGION_EU433 ) || defined( REGION_EU868 ) || \ + defined( REGION_IN865 ) || defined( REGION_KR920 ) + #define REGION_NVM_MAX_NB_CHANNELS 16 +#else + // Region_RU864 + #define REGION_NVM_MAX_NB_CHANNELS 8 +#endif + +// Selection of REGION_NVM_MAX_NB_BANDS +#if defined( REGION_EU868 ) + #define REGION_NVM_MAX_NB_BANDS 6 +#else + // All others + #define REGION_NVM_MAX_NB_BANDS 1 +#endif + +// Selection of REGION_NVM_CHANNELS_MASK_SIZE +#if defined( REGION_CN470 ) || defined( REGION_US915 ) || \ + defined( REGION_AU915 ) + #define REGION_NVM_CHANNELS_MASK_SIZE 6 +#else + // All others + #define REGION_NVM_CHANNELS_MASK_SIZE 1 +#endif + +/*! + * Region specific data which must be stored in the NVM. + */ +typedef struct sRegionNvmDataGroup1 +{ + /*! + * LoRaMac bands + */ + Band_t Bands[ REGION_NVM_MAX_NB_BANDS ]; +#if defined( REGION_US915 ) || defined( REGION_AU915 ) + /*! + * LoRaMac channels remaining + */ + uint16_t ChannelsMaskRemaining[ REGION_NVM_CHANNELS_MASK_SIZE ]; + /*! + * Index of current in use 8 bit group (0: bit 0 - 7, 1: bit 8 - 15, ..., + * 7: bit 56 - 63) + */ + uint8_t JoinChannelGroupsCurrentIndex; + /*! + * Counter of join trials needed to alternate between datarates. + */ + uint8_t JoinTrialsCounter; +#endif + /*! + * CRC32 value of the Region data structure. + */ + uint32_t Crc32; +}RegionNvmDataGroup1_t; + +/*! + * Region specific data which must be stored in the NVM. + * Parameters which do not change very frequently. + */ +typedef struct sRegionNvmDataGroup2 +{ + /*! + * LoRaMAC channels + */ + ChannelParams_t Channels[ REGION_NVM_MAX_NB_CHANNELS ]; + /*! + * LoRaMac channels mask + */ + uint16_t ChannelsMask[ REGION_NVM_CHANNELS_MASK_SIZE ]; + /*! + * LoRaMac channels default mask + */ + uint16_t ChannelsDefaultMask[ REGION_NVM_CHANNELS_MASK_SIZE ]; + /*! + * CRC32 value of the Region data structure. + */ + uint32_t Crc32; +}RegionNvmDataGroup2_t; + +/*! \} addtogroup REGIONCOMMON */ + +#ifdef __cplusplus +} +#endif + +#endif // __REGIONNVM_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.c index 468523ad..a3659c56 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.c @@ -28,82 +28,32 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionRU864.c + * @author MCD Application Team + * @brief Region implementation for RU864 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionRU864.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionRU864NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ RU864_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ RU864_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionRU864NvmCtx_t; - +#if defined( REGION_RU864 ) /* * Non-volatile module context. */ -static RegionRU864NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsRU864[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - static bool VerifyRfFreq( uint32_t freq ) { // Check radio driver support @@ -123,7 +73,7 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesRU864[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsRU864 ); TimerTime_t timeOnAir = 0; if( datarate == DR_7 ) @@ -136,11 +86,13 @@ static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) } return timeOnAir; } +#endif /* REGION_RU864 */ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_RU864 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -160,7 +112,16 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, RU864_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )RU864_TX_MAX_DATARATE, + .MinDr = ( int8_t )RU864_TX_MIN_DATARATE, + .NbChannels = RU864_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -175,12 +136,12 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = RU864_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = RU864_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -188,11 +149,13 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateRU864[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterRU864[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = RU864_DUTY_CYCLE_ENABLED; @@ -205,37 +168,37 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = RU864_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = RU864_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = RU864_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = RU864_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = RU864_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( RU864_ACKTIMEOUT + randr( -RU864_ACK_TIMEOUT_RND, RU864_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = RU864_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -250,12 +213,12 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -265,13 +228,17 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = RU864_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -318,7 +285,7 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsRU864 ); break; } default: @@ -327,17 +294,21 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_RU864 */ return phyParam; } void RegionRU864SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_RU864 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_RU864 */ } void RegionRU864InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_RU864 ) Band_t bands[RU864_MAX_NB_BANDS] = { RU864_BAND0 @@ -347,41 +318,41 @@ void RegionRU864InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * RU864_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * RU864_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) RU864_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) RU864_LC2; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) RU864_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) RU864_LC2; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -389,16 +360,12 @@ void RegionRU864InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionRU864GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionRU864NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_RU864 */ } bool RegionRU864Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_RU864 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -430,10 +397,14 @@ bool RegionRU864Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_RU864 */ } void RegionRU864ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_RU864 ) ChannelParams_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; @@ -489,52 +460,58 @@ void RegionRU864ApplyCFList( ApplyCFListParams_t* applyCFList ) RegionRU864ChannelsRemove( &channelRemove ); } } +#endif /* REGION_RU864 */ } bool RegionRU864ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_RU864 ) switch( chanMaskSet->ChannelsMaskType ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_RU864 */ } void RegionRU864ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_RU864 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, RU864_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsRU864 ); if( rxConfigParams->Datarate == DR_7 ) { // FSK - tSymbol = RegionCommonComputeSymbolTimeFsk( DataratesRU864[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeFsk( DataratesRU864[rxConfigParams->Datarate] ); } else { // LoRa - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesRU864[rxConfigParams->Datarate], BandwidthsRU864[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesRU864[rxConfigParams->Datarate], BandwidthsRU864[rxConfigParams->Datarate] ); } - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_RU864 */ } bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_RU864 ) RadioModems_t modem; int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; @@ -549,11 +526,11 @@ bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -574,6 +551,7 @@ bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterRU864[dr]; @@ -584,27 +562,33 @@ bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) } Radio.SetMaxPayloadLength( modem, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_RU864 */ } bool RegionRU864TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_RU864 ) RadioModems_t modem; int8_t phyDr = DataratesRU864[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsRU864 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -617,7 +601,7 @@ bool RegionRU864TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); } /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Update time-on-air @@ -628,11 +612,15 @@ bool RegionRU864TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_RU864 */ } uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_RU864 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; @@ -675,7 +663,7 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -683,7 +671,7 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -709,7 +697,7 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = RU864_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = RU864_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = RU864_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -721,9 +709,9 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -732,12 +720,14 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_RU864 */ return status; } uint8_t RegionRU864RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_RU864 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -757,10 +747,11 @@ uint8_t RegionRU864RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_RU864 */ return status; } -uint8_t RegionRU864NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionRU864NewChannelReq( NewChannelReqParams_t* newChannelReq ) { uint8_t status = 0x03; ChannelAddParams_t channelAdd; @@ -815,12 +806,14 @@ uint8_t RegionRU864NewChannelReq( NewChannelReqParams_t* newChannelReq ) int8_t RegionRU864TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { uint8_t status = 0x03; +#if defined( REGION_RU864 ) // Verify if the frequency is supported if( VerifyRfFreq( dlChannelReq->Rx1Frequency ) == false ) @@ -829,7 +822,7 @@ uint8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -837,39 +830,46 @@ uint8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } +#endif /* REGION_RU864 */ return status; } int8_t RegionRU864AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_RU864 ) return currentDr; +#else + return -1; +#endif /* REGION_RU864 */ } LoRaMacStatus_t RegionRU864NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_RU864 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[RU864_MAX_NB_CHANNELS] = { 0 }; RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; + uint16_t joinChannels = RU864_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = RU864_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = RU864_JOIN_CHANNELS; + countChannelsParams.JoinChannels = &joinChannels; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; @@ -893,13 +893,17 @@ LoRaMacStatus_t RegionRU864NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_RU864 */ } LoRaMacStatus_t RegionRU864ChannelAdd( ChannelAddParams_t* channelAdd ) { +#if defined( REGION_RU864 ) bool drInvalid = false; bool freqInvalid = false; uint8_t id = channelAdd->ChannelId; @@ -951,14 +955,18 @@ LoRaMacStatus_t RegionRU864ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_RU864 */ } bool RegionRU864ChannelsRemove( ChannelRemoveParams_t* channelRemove ) { +#if defined( REGION_RU864 ) uint8_t id = channelRemove->ChannelId; if( id < RU864_NUMB_DEFAULT_CHANNELS ) @@ -967,25 +975,31 @@ bool RegionRU864ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, RU864_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, RU864_MAX_NB_CHANNELS ); +#else + return false; +#endif /* REGION_RU864 */ } void RegionRU864SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_RU864 ) + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_RU864 */ } uint8_t RegionRU864ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_RU864 ) int8_t datarate = dr - drOffset; if( datarate < 0 ) @@ -993,10 +1007,14 @@ uint8_t RegionRU864ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d datarate = DR_0; } return datarate; +#else + return 0; +#endif /* REGION_RU864 */ } void RegionRU864RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_RU864 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesRU864; @@ -1011,4 +1029,5 @@ void RegionRU864RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = RU864_BEACON_CHANNEL_DR; +#endif /* REGION_RU864 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.h index 5776d5a1..89327d26 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionRU864.h @@ -32,6 +32,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionRU864.h + * @author MCD Application Team + * @brief Region definition for RU864 + ****************************************************************************** + */ #ifndef __REGION_RU864_H__ #define __REGION_RU864_H__ @@ -92,11 +102,6 @@ extern "C" */ #define RU864_MAX_RX1_DR_OFFSET 5 -/*! - * Default Rx1 receive datarate offset - */ -#define RU864_DEFAULT_RX1_DR_OFFSET 0 - /*! * Minimal Tx output power that can be used by the node */ @@ -122,16 +127,6 @@ extern "C" */ #define RU864_DEFAULT_ANTENNA_GAIN 2.15f -/*! - * ADR Ack limit - */ -#define RU864_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define RU864_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -142,41 +137,6 @@ extern "C" */ #define RU864_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define RU864_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define RU864_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define RU864_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define RU864_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define RU864_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define RU864_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define RU864_ACK_TIMEOUT_RND 1000 - #if ( RU864_DEFAULT_DATARATE > DR_5 ) #error "A default DR higher than DR_5 may lead to connectivity loss." #endif @@ -191,6 +151,11 @@ extern "C" */ #define RU864_RX_WND_2_DR DR_0 +/*! + * Default uplink dwell time configuration + */ +#define RU864_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -241,9 +206,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define RU864_BAND0 { 100 , RU864_MAX_TX_POWER, 0, 0, 0, 0 } // 1.0 % +#define RU864_BAND0 { 100 , RU864_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -273,6 +238,7 @@ static const uint8_t DataratesRU864[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; */ static const uint32_t BandwidthsRU864[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ @@ -282,6 +248,7 @@ static const uint8_t MaxPayloadOfDatarateRU864[] = { 51, 51, 51, 115, 242, 242, * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterRU864[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -306,15 +273,6 @@ void RegionRU864SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionRU864InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionRU864GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -407,7 +365,7 @@ uint8_t RegionRU864RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionRU864NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionRU864NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -427,7 +385,7 @@ int8_t RegionRU864TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.c b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.c index 6fdeca8a..b8fae757 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.c +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.c @@ -28,10 +28,21 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionUS915.c + * @author MCD Application Team + * @brief Region implementation for US915 + ****************************************************************************** + */ +#include "radio.h" #include "RegionCommon.h" #include "RegionUS915.h" +#include "RegionBaseUS.h" +#include "lorawan_conf.h" /* REGION_* */ // Definitions #define CHANNELS_MASK_SIZE 6 @@ -39,182 +50,19 @@ // A mask to select only valid 500KHz channels #define CHANNELS_MASK_500KHZ_MASK 0x00FF -/*! - * Region specific context - */ -typedef struct sRegionUS915NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ US915_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ US915_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels remaining - */ - uint16_t ChannelsMaskRemaining[CHANNELS_MASK_SIZE]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; - /*! - * Index of current in use 8 bit group (0: bit 0 - 7, 1: bit 8 - 15, ..., 7: bit 56 - 63) - */ - uint8_t JoinChannelGroupsCurrentIndex; - /*! - * Counter of join trials needed to alternate between DR0 and DR4, see \ref RegionUS915AlternateDr - */ - uint8_t JoinTrialsCounter; -}RegionUS915NvmCtx_t; - +#if defined( REGION_US915 ) /* * Non-volatile module context. */ -static RegionUS915NvmCtx_t NvmCtx; - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -/*! - * \brief Searches for available 125 kHz channels in the given channel mask. - * - * \param [IN] channelMaskRemaining The remaining channel mask. - * - * \param [OUT] findAvailableChannelsIndex List containing the indexes of all available 125 kHz channels. - * - * \param [OUT] availableChannels Number of available 125 kHz channels. - * - * \retval Status - */ -static LoRaMacStatus_t FindAvailable125kHzChannels( uint8_t* findAvailableChannelsIndex, uint16_t channelMaskRemaining, uint8_t* availableChannels ) -{ - // Nullpointer check - if( findAvailableChannelsIndex == NULL || availableChannels == NULL ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - - // Initialize counter - *availableChannels = 0; - for( uint8_t i = 0; i < 8; i++ ) - { - // Find available channels - if( ( channelMaskRemaining & ( 1 << i ) ) != 0 ) - { - // Save available channel index - findAvailableChannelsIndex[*availableChannels] = i; - // Increment counter of available channels if the current channel is available - ( *availableChannels )++; - } - } - - return LORAMAC_STATUS_OK; -} - -/*! - * \brief Computes the next 125kHz channel used for join requests. - * - * \param [OUT] newChannelIndex Index of available channel. - * - * \retval Status - */ -static LoRaMacStatus_t ComputeNext125kHzJoinChannel( uint8_t* newChannelIndex ) -{ - uint8_t currentChannelsMaskRemainingIndex; - uint16_t channelMaskRemaining; - uint8_t findAvailableChannelsIndex[8] = { 0 }; - uint8_t availableChannels = 0; - uint8_t startIndex = NvmCtx.JoinChannelGroupsCurrentIndex; - - // Null pointer check - if( newChannelIndex == NULL ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - - do { - // Current ChannelMaskRemaining, two groups per channel mask. For example Group 0 and 1 (8 bit) are ChannelMaskRemaining 0 (16 bit), etc. - currentChannelsMaskRemainingIndex = (uint8_t) startIndex / 2; - - // For even numbers we need the 8 LSBs and for uneven the 8 MSBs - if( ( startIndex % 2 ) == 0 ) - { - channelMaskRemaining = ( NvmCtx.ChannelsMaskRemaining[currentChannelsMaskRemainingIndex] & 0x00FF ); - } - else - { - channelMaskRemaining = ( ( NvmCtx.ChannelsMaskRemaining[currentChannelsMaskRemainingIndex] >> 8 ) & 0x00FF ); - } - - - if( FindAvailable125kHzChannels( findAvailableChannelsIndex, channelMaskRemaining, &availableChannels ) == LORAMAC_STATUS_PARAMETER_INVALID ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - - if ( availableChannels > 0 ) - { - // Choose randomly a free channel 125kHz - *newChannelIndex = ( startIndex * 8 ) + findAvailableChannelsIndex[randr( 0, ( availableChannels - 1 ) )]; - } - - // Increment start index - startIndex++; - if ( startIndex > 7 ) - { - startIndex = 0; - } - } while( ( availableChannels == 0 ) && ( startIndex != NvmCtx.JoinChannelGroupsCurrentIndex ) ); - - if ( availableChannels > 0 ) - { - NvmCtx.JoinChannelGroupsCurrentIndex = startIndex; - return LORAMAC_STATUS_OK; - } - - return LORAMAC_STATUS_PARAMETER_INVALID; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsUS915[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) { int8_t txPowerResult = txPower; // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); + txPowerResult = RegionCommonLimitTxPower( txPower, maxBandTxPower ); if( datarate == DR_4 ) {// Limit tx power to max 26dBm @@ -257,15 +105,17 @@ static bool VerifyRfFreq( uint32_t freq ) static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen ) { int8_t phyDr = DataratesUS915[datarate]; - uint32_t bandwidth = GetBandwidth( datarate ); + uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsUS915 ); return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true ); } +#endif /* REGION_US915 */ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) { PhyParam_t phyParam = { 0 }; +#if defined( REGION_US915 ) switch( getPhy->Attribute ) { case PHY_MIN_RX_DR: @@ -285,7 +135,16 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, US915_TX_MIN_DATARATE ); + RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams = + { + .CurrentDr = getPhy->Datarate, + .MaxDr = ( int8_t )US915_TX_MAX_DATARATE, + .MinDr = ( int8_t )US915_TX_MIN_DATARATE, + .NbChannels = US915_MAX_NB_CHANNELS, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, + }; + phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; } case PHY_MAX_TX_POWER: @@ -300,12 +159,12 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_DEF_ADR_ACK_LIMIT: { - phyParam.Value = US915_ADR_ACK_LIMIT; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT; break; } case PHY_DEF_ADR_ACK_DELAY: { - phyParam.Value = US915_ADR_ACK_DELAY; + phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY; break; } case PHY_MAX_PAYLOAD: @@ -313,11 +172,13 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = MaxPayloadOfDatarateUS915[getPhy->Datarate]; break; } + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ case PHY_MAX_PAYLOAD_REPEATER: { phyParam.Value = MaxPayloadOfDatarateRepeaterUS915[getPhy->Datarate]; break; } + /* ST_WORKAROUND_END */ case PHY_DUTY_CYCLE: { phyParam.Value = US915_DUTY_CYCLE_ENABLED; @@ -330,37 +191,37 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_RECEIVE_DELAY1: { - phyParam.Value = US915_RECEIVE_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1; break; } case PHY_RECEIVE_DELAY2: { - phyParam.Value = US915_RECEIVE_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2; break; } case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = US915_JOIN_ACCEPT_DELAY1; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1; break; } case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = US915_JOIN_ACCEPT_DELAY2; + phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2; break; } case PHY_MAX_FCNT_GAP: { - phyParam.Value = US915_MAX_FCNT_GAP; + phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP; break; } case PHY_ACK_TIMEOUT: { - phyParam.Value = ( US915_ACKTIMEOUT + randr( -US915_ACK_TIMEOUT_RND, US915_ACK_TIMEOUT_RND ) ); + phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) ); break; } case PHY_DEF_DR1_OFFSET: { - phyParam.Value = US915_DEFAULT_RX1_DR_OFFSET; + phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET; break; } case PHY_DEF_RX2_FREQUENCY: @@ -375,12 +236,12 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -390,13 +251,17 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: + { + phyParam.Value = US915_DEFAULT_UPLINK_DWELL_TIME; + break; + } case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; + phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME; break; } case PHY_DEF_MAX_EIRP: @@ -411,7 +276,9 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BEACON_CHANNEL_FREQ: { - phyParam.Value = US915_BEACON_CHANNEL_FREQ + ( getPhy->Channel * US915_BEACON_CHANNEL_STEPWIDTH ); + phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel, + US915_BEACON_CHANNEL_FREQ, + US915_BEACON_CHANNEL_STEPWIDTH ); break; } case PHY_BEACON_FORMAT: @@ -426,16 +293,6 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = US915_BEACON_CHANNEL_DR; break; } - case PHY_BEACON_CHANNEL_STEPWIDTH: - { - phyParam.Value = US915_BEACON_CHANNEL_STEPWIDTH; - break; - } - case PHY_PING_SLOT_NB_CHANNELS: - { - phyParam.Value = US915_PING_SLOT_NB_CHANNELS; - break; - } case PHY_BEACON_NB_CHANNELS: { phyParam.Value = US915_BEACON_NB_CHANNELS; @@ -443,7 +300,9 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_PING_SLOT_CHANNEL_FREQ: { - phyParam.Value = US915_PING_SLOT_CHANNEL_FREQ + ( getPhy->Channel * US915_BEACON_CHANNEL_STEPWIDTH ); + phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel, + US915_PING_SLOT_CHANNEL_FREQ, + US915_BEACON_CHANNEL_STEPWIDTH ); break; } case PHY_PING_SLOT_CHANNEL_DR: @@ -451,6 +310,11 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) phyParam.Value = US915_PING_SLOT_CHANNEL_DR; break; } + case PHY_PING_SLOT_NB_CHANNELS: + { + phyParam.Value = US915_BEACON_NB_CHANNELS; + break; + } case PHY_SF_FROM_DR: { phyParam.Value = DataratesUS915[getPhy->Datarate]; @@ -458,7 +322,7 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_BW_FROM_DR: { - phyParam.Value = GetBandwidth( getPhy->Datarate ); + phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsUS915 ); break; } default: @@ -467,17 +331,21 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } } +#endif /* REGION_US915 */ return phyParam; } void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], +#if defined( REGION_US915 ) + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); +#endif /* REGION_US915 */ } void RegionUS915InitDefaults( InitDefaultsParams_t* params ) { +#if defined( REGION_US915 ) Band_t bands[US915_MAX_NB_BANDS] = { US915_BAND0 @@ -487,55 +355,63 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Initialize 8 bit channel groups index - NvmCtx.JoinChannelGroupsCurrentIndex = 0; + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; // Initialize the join trials counter - NvmCtx.JoinTrialsCounter = 0; + RegionNvmGroup1->JoinTrialsCounter = 0; // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * US915_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * US915_MAX_NB_BANDS ); // Default channels for( uint8_t i = 0; i < US915_MAX_NB_CHANNELS - 8; i++ ) { // 125 kHz channels - NvmCtx.Channels[i].Frequency = 902300000 + i * 200000; - NvmCtx.Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 902300000 + i * 200000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; + RegionNvmGroup2->Channels[i].Band = 0; } for( uint8_t i = US915_MAX_NB_CHANNELS - 8; i < US915_MAX_NB_CHANNELS; i++ ) { // 500 kHz channels - NvmCtx.Channels[i].Frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; - NvmCtx.Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; + RegionNvmGroup2->Channels[i].Band = 0; } // Default ChannelsMask /* ST_WORKAROUND_BEGIN: Hybrid mode */ #if ( HYBRID_ENABLED == 1 ) - NvmCtx.ChannelsDefaultMask[0] = 0x00FF; - NvmCtx.ChannelsDefaultMask[1] = 0x0000; - NvmCtx.ChannelsDefaultMask[2] = 0x0000; - NvmCtx.ChannelsDefaultMask[3] = 0x0000; - NvmCtx.ChannelsDefaultMask[4] = 0x0001; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0x00FF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0x0001; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; #else - NvmCtx.ChannelsDefaultMask[0] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[1] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[2] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[3] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[4] = 0x00FF; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0x00FF; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; #endif /* HYBRID_ENABLED == 1 */ /* ST_WORKAROUND_END */ // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); // Copy into channels mask remaining - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: @@ -545,19 +421,11 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params ) case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); - for( uint8_t i = 0; i < 6; i++ ) + for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; - } - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } @@ -566,16 +434,12 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params ) break; } } -} - -void* RegionUS915GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionUS915NvmCtx_t ); - return &NvmCtx; +#endif /* REGION_US915 */ } bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { +#if defined( REGION_US915 ) switch( phyAttribute ) { case PHY_FREQUENCY: @@ -583,12 +447,9 @@ bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) return VerifyRfFreq( verify->Frequency ); } case PHY_TX_DR: - { - return RegionCommonValueInRange( verify->DatarateParams.Datarate, US915_TX_MIN_DATARATE, US915_TX_MAX_DATARATE ); - } case PHY_DEF_TX_DR: { - return RegionCommonValueInRange( verify->DatarateParams.Datarate, DR_0, DR_5 ); + return RegionCommonValueInRange( verify->DatarateParams.Datarate, US915_TX_MIN_DATARATE, US915_TX_MAX_DATARATE ); } case PHY_RX_DR: { @@ -607,10 +468,14 @@ bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) default: return false; } +#else + return false; +#endif /* REGION_US915 */ } void RegionUS915ApplyCFList( ApplyCFListParams_t* applyCFList ) { +#if defined( REGION_US915 ) // Size of the optional CF list must be 16 byte if( applyCFList->Size != 16 ) { @@ -626,19 +491,21 @@ void RegionUS915ApplyCFList( ApplyCFListParams_t* applyCFList ) // ChMask0 - ChMask4 must be set (every ChMask has 16 bit) for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 4; chMaskItr++, cntPayload+=2 ) { - NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); - NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); + RegionNvmGroup2->ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); + RegionNvmGroup2->ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); if( chMaskItr == 4 ) { - NvmCtx.ChannelsMask[chMaskItr] = NvmCtx.ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsMask[chMaskItr] = RegionNvmGroup2->ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; } // Set the channel mask to the remaining - NvmCtx.ChannelsMaskRemaining[chMaskItr] &= NvmCtx.ChannelsMask[chMaskItr]; + RegionNvmGroup1->ChannelsMaskRemaining[chMaskItr] &= RegionNvmGroup2->ChannelsMask[chMaskItr]; } +#endif /* REGION_US915 */ } bool RegionUS915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { +#if defined( REGION_US915 ) uint8_t nbChannels = RegionCommonCountChannels( chanMaskSet->ChannelsMaskIn, 0, 4 ); // Check the number of active channels @@ -652,45 +519,49 @@ bool RegionUS915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); - NvmCtx.ChannelsDefaultMask[4] = NvmCtx.ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[4] = RegionNvmGroup2->ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: return false; } return true; +#else + return false; +#endif /* REGION_US915 */ } void RegionUS915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) { - /* ST_WORKAROUND_BEGIN: remove float/double */ - uint32_t tSymbol = 0; - /* ST_WORKAROUND_END */ +#if defined( REGION_US915 ) + uint32_t tSymbolInUs = 0; // Get the datarate, perform a boundary check rxConfigParams->Datarate = MIN( datarate, US915_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsUS915 ); - tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesUS915[rxConfigParams->Datarate], BandwidthsUS915[rxConfigParams->Datarate] ); + tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesUS915[rxConfigParams->Datarate], BandwidthsUS915[rxConfigParams->Datarate] ); - RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); +#endif /* REGION_US915 */ } bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { +#if defined( REGION_US915 ) int8_t dr = rxConfig->Datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; @@ -715,6 +586,7 @@ bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) // Radio configuration Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); + /* ST_WORKAROUND_BEGIN: Keep repeater feature */ if( rxConfig->RepeaterSupport == true ) { maxPayload = MaxPayloadOfDatarateRepeaterUS915[dr]; @@ -723,31 +595,38 @@ bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) { maxPayload = MaxPayloadOfDatarateUS915[dr]; } + Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ); + /* ST_WORKAROUND_END */ + /* ST_WORKAROUND_BEGIN: Print Rx config */ RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr); /* ST_WORKAROUND_END */ *datarate = (uint8_t) dr; return true; +#else + return false; +#endif /* REGION_US915 */ } bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { +#if defined( REGION_US915 ) int8_t phyDr = DataratesUS915[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, RegionNvmGroup2->ChannelsMask ); + uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsUS915 ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); /* ST_WORKAROUND_BEGIN: Print Tx config */ - RegionCommonTxConfigPrint(NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate); + RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate); /* ST_WORKAROUND_END */ // Setup maximum payload length of the radio driver @@ -758,24 +637,29 @@ bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime *txPower = txPowerLimited; return true; +#else + return false; +#endif /* REGION_US915 */ } uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) { uint8_t status = 0x07; +#if defined( REGION_US915 ) RegionCommonLinkAdrParams_t linkAdrParams = { 0 }; uint8_t nextIndex = 0; uint8_t bytesProcessed = 0; - uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; + uint16_t channelsMask[CHANNELS_MASK_SIZE] = { 0, 0, 0, 0, 0, 0 }; GetPhyParams_t getPhy; PhyParam_t phyParam; RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; // Initialize local copy of channels mask - RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, 6 ); + RegionCommonChanMaskCopy( channelsMask, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); while( bytesProcessed < linkAdrReq->PayloadSize ) { + // Get ADR request parameters nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); if( nextIndex == 0 ) @@ -890,7 +774,7 @@ uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = channelsMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = US915_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = US915_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = US915_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -902,14 +786,14 @@ uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Copy Mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 ); - - NvmCtx.ChannelsMaskRemaining[0] &= NvmCtx.ChannelsMask[0]; - NvmCtx.ChannelsMaskRemaining[1] &= NvmCtx.ChannelsMask[1]; - NvmCtx.ChannelsMaskRemaining[2] &= NvmCtx.ChannelsMask[2]; - NvmCtx.ChannelsMaskRemaining[3] &= NvmCtx.ChannelsMask[3]; - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; - NvmCtx.ChannelsMaskRemaining[5] = NvmCtx.ChannelsMask[5]; + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, channelsMask, 6 ); + + RegionNvmGroup1->ChannelsMaskRemaining[0] &= RegionNvmGroup2->ChannelsMask[0]; + RegionNvmGroup1->ChannelsMaskRemaining[1] &= RegionNvmGroup2->ChannelsMask[1]; + RegionNvmGroup1->ChannelsMaskRemaining[2] &= RegionNvmGroup2->ChannelsMask[2]; + RegionNvmGroup1->ChannelsMaskRemaining[3] &= RegionNvmGroup2->ChannelsMask[3]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[5] = RegionNvmGroup2->ChannelsMask[5]; } // Update status variables @@ -918,12 +802,14 @@ uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in *nbRepOut = linkAdrParams.NbRep; *nbBytesParsed = bytesProcessed; +#endif /* REGION_US915 */ return status; } uint8_t RegionUS915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) { uint8_t status = 0x07; +#if defined( REGION_US915 ) // Verify radio frequency if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false ) @@ -948,39 +834,43 @@ uint8_t RegionUS915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) status &= 0xFB; // Rx1DrOffset range KO } +#endif /* REGION_US915 */ return status; } -uint8_t RegionUS915NewChannelReq( NewChannelReqParams_t* newChannelReq ) +int8_t RegionUS915NewChannelReq( NewChannelReqParams_t* newChannelReq ) { - // Datarate and frequency KO - return 0; + // Do not accept the request + return -1; } int8_t RegionUS915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) { + // Do not accept the request return -1; } -uint8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq ) +int8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq ) { - return 0; + // Do not accept the request + return -1; } int8_t RegionUS915AlternateDr( int8_t currentDr, AlternateDrType_t type ) { +#if defined( REGION_US915 ) // Alternates the data rate according to the channel sequence: // Eight times a 125kHz DR_0 and then one 500kHz DR_4 channel if( type == ALTERNATE_DR ) { - NvmCtx.JoinTrialsCounter++; + RegionNvmGroup1->JoinTrialsCounter++; } else { - NvmCtx.JoinTrialsCounter--; + RegionNvmGroup1->JoinTrialsCounter--; } - if( NvmCtx.JoinTrialsCounter % 9 == 0 ) + if( RegionNvmGroup1->JoinTrialsCounter % 9 == 0 ) { // Use DR_4 every 9th times. currentDr = DR_4; @@ -990,54 +880,57 @@ int8_t RegionUS915AlternateDr( int8_t currentDr, AlternateDrType_t type ) currentDr = DR_0; } return currentDr; +#else + return -1; +#endif /* REGION_US915 */ } LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) { +#if defined( REGION_US915 ) uint8_t nbEnabledChannels = 0; uint8_t nbRestrictedChannels = 0; uint8_t enabledChannels[US915_MAX_NB_CHANNELS] = { 0 }; - uint8_t newChannelIndex = 0; RegionCommonIdentifyChannelsParam_t identifyChannelsParam; RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams; LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; // Count 125kHz channels - if( RegionCommonCountChannels( NvmCtx.ChannelsMaskRemaining, 0, 4 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup1->ChannelsMaskRemaining, 0, 4 ) == 0 ) { // Reactivate default channels - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 4 ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, 4 ); - NvmCtx.JoinChannelGroupsCurrentIndex = 0; + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; } // Check other channels if( nextChanParams->Datarate >= DR_4 ) { - if( ( NvmCtx.ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) + if( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) { - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; } } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMaskRemaining; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup1->ChannelsMaskRemaining; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = US915_MAX_NB_CHANNELS; - countChannelsParams.JoinChannels = 0; + countChannelsParams.JoinChannels = NULL; identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff; identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx; identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled; identifyChannelsParam.MaxBands = US915_MAX_NB_BANDS; - identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams; - identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp; identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest; identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen ); + identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams; + status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels, &nbEnabledChannels, &nbRestrictedChannels, time ); @@ -1058,18 +951,18 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_ // 125kHz Channels (0 - 63) DR0 if( nextChanParams->Datarate == DR_0 ) { - if( ComputeNext125kHzJoinChannel( &newChannelIndex ) == LORAMAC_STATUS_PARAMETER_INVALID ) + if( RegionBaseUSComputeNext125kHzJoinChannel( ( uint16_t* ) RegionNvmGroup1->ChannelsMaskRemaining, + &RegionNvmGroup1->JoinChannelGroupsCurrentIndex, channel ) == LORAMAC_STATUS_PARAMETER_INVALID ) { return LORAMAC_STATUS_PARAMETER_INVALID; } - *channel = newChannelIndex; } // 500kHz Channels (64 - 71) DR4 else { // Choose the next available channel uint8_t i = 0; - while( ( ( NvmCtx.ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 ) + while( ( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 ) { i++; } @@ -1078,9 +971,12 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_ } // Disable the channel in the mask - RegionCommonChanDisable( NvmCtx.ChannelsMaskRemaining, *channel, US915_MAX_NB_CHANNELS ); + RegionCommonChanDisable( RegionNvmGroup1->ChannelsMaskRemaining, *channel, US915_MAX_NB_CHANNELS ); } return status; +#else + return LORAMAC_STATUS_NO_CHANNEL_FOUND; +#endif /* REGION_US915 */ } LoRaMacStatus_t RegionUS915ChannelAdd( ChannelAddParams_t* channelAdd ) @@ -1095,18 +991,21 @@ bool RegionUS915ChannelsRemove( ChannelRemoveParams_t* channelRemove ) void RegionUS915SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); +#if defined( REGION_US915 ) + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, RegionNvmGroup2->ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); +#endif /* REGION_US915 */ } uint8_t RegionUS915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) { +#if defined( REGION_US915 ) int8_t datarate = DatarateOffsetsUS915[dr][drOffset]; if( datarate < 0 ) @@ -1114,10 +1013,14 @@ uint8_t RegionUS915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t d datarate = DR_0; } return datarate; +#else + return 0; +#endif /* REGION_US915 */ } void RegionUS915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) { +#if defined( REGION_US915 ) RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup; regionCommonRxBeaconSetup.Datarates = DataratesUS915; @@ -1132,4 +1035,5 @@ void RegionUS915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr ) // Store downlink datarate *outDr = US915_BEACON_CHANNEL_DR; +#endif /* REGION_US915 */ } diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.h b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.h index bfaf4e29..12ffc957 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/Region/RegionUS915.h @@ -34,6 +34,16 @@ * Implementation according to LoRaWAN Specification v1.0.2. * \{ */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file RegionUS915.h + * @author MCD Application Team + * @brief Region definition for US915 + ****************************************************************************** + */ #ifndef __REGION_US915_H__ #define __REGION_US915_H__ @@ -84,11 +94,7 @@ extern "C" */ #define US915_MAX_RX1_DR_OFFSET 3 -/*! - * Default Rx1 receive datarate offset - */ -#define US915_DEFAULT_RX1_DR_OFFSET 0 - +/* ST_WORKAROUND_BEGIN: Certification requirement */ /*! * Minimal Tx output power that can be used by the node */ @@ -97,6 +103,8 @@ extern "C" #else #define US915_MIN_TX_POWER TX_POWER_14 #endif /* CERTIF_LORAWAN_VERSION */ +/* ST_WORKAROUND_END */ + /*! * Maximal Tx output power that can be used by the node */ @@ -112,16 +120,6 @@ extern "C" */ #define US915_DEFAULT_MAX_ERP 30.0f -/*! - * ADR Ack limit - */ -#define US915_ADR_ACK_LIMIT 64 - -/*! - * ADR Ack delay - */ -#define US915_ADR_ACK_DELAY 32 - /*! * Enabled or disabled the duty cycle */ @@ -132,41 +130,6 @@ extern "C" */ #define US915_MAX_RX_WINDOW 3000 -/*! - * Receive delay 1 - */ -#define US915_RECEIVE_DELAY1 1000 - -/*! - * Receive delay 2 - */ -#define US915_RECEIVE_DELAY2 2000 - -/*! - * Join accept delay 1 - */ -#define US915_JOIN_ACCEPT_DELAY1 5000 - -/*! - * Join accept delay 2 - */ -#define US915_JOIN_ACCEPT_DELAY2 6000 - -/*! - * Maximum frame counter gap - */ -#define US915_MAX_FCNT_GAP 16384 - -/*! - * Ack timeout - */ -#define US915_ACKTIMEOUT 2000 - -/*! - * Random ack timeout limits - */ -#define US915_ACK_TIMEOUT_RND 1000 - /*! * Second reception window channel frequency definition. */ @@ -177,6 +140,11 @@ extern "C" */ #define US915_RX_WND_2_DR DR_8 +/*! + * Default uplink dwell time configuration + */ +#define US915_DEFAULT_UPLINK_DWELL_TIME 0 + /* * CLASS B */ @@ -195,11 +163,6 @@ extern "C" */ #define US915_PING_SLOT_CHANNEL_FREQ 923300000 -/*! - * Number of possible ping slot channels - */ -#define US915_PING_SLOT_NB_CHANNELS 8 - /*! * Number of possible beacon channels */ @@ -242,9 +205,9 @@ extern "C" /*! * Band 0 definition - * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } + * Band = { DutyCycle, TxMaxPower, LastBandUpdateTime, LastMaxCreditAssignTime, TimeCredits, MaxTimeCredits, ReadyForTransmission } */ -#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0, 0, 0 } // 100.0 % +#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0, 0, 0, 0 } // 100.0 % /*! * Defines the first channel for RX window 1 for US band @@ -283,6 +246,7 @@ static const int8_t DatarateOffsetsUS915[5][4] = { DR_13, DR_13, DR_12, DR_11 }, // DR_4 }; +/* ST_WORKAROUND_BEGIN: Keep repeater feature */ /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ @@ -292,6 +256,7 @@ static const uint8_t MaxPayloadOfDatarateUS915[] = { 11, 53, 125, 242, 242, 0, 0 * Maximum payload with respect to the datarate index. Can operate with repeater. */ static const uint8_t MaxPayloadOfDatarateRepeaterUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; +/* ST_WORKAROUND_END */ /*! * \brief The function gets a value of a specific phy attribute. @@ -316,15 +281,6 @@ void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionUS915InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionUS915GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * @@ -417,7 +373,7 @@ uint8_t RegionUS915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionUS915NewChannelReq( NewChannelReqParams_t* newChannelReq ); +int8_t RegionUS915NewChannelReq( NewChannelReqParams_t* newChannelReq ); /*! * \brief The function processes a TX ParamSetup Request. @@ -437,7 +393,7 @@ int8_t RegionUS915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); * * \retval Returns the status of the operation, according to the LoRaMAC specification. */ -uint8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq ); +int8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq ); /*! * \brief Alternates the datarate of the channel for the join request. diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/secure-element-nvm.h b/Middlewares/Third_Party/LoRaWAN/Mac/secure-element-nvm.h new file mode 100644 index 00000000..b3576b31 --- /dev/null +++ b/Middlewares/Third_Party/LoRaWAN/Mac/secure-element-nvm.h @@ -0,0 +1,147 @@ +/*! + * \file secure-element-nvm.h + * + * \brief Secure Element non-volatile data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \addtogroup SECUREELEMENT + * + * \{ + * + */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file secure-element-nvm.h + * @author MCD Application Team + * @brief Secure Element non-volatile data. + ****************************************************************************** + */ +#ifndef __SECURE_ELEMENT_NVM_H__ +#define __SECURE_ELEMENT_NVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "LoRaMacTypes.h" +#include "lorawan_conf.h" /* LORAWAN_KMS */ +#if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) +#else /* LORAWAN_KMS == 1 */ +#include "kms_if.h" +#endif /* LORAWAN_KMS */ + +/*! + * Secure-element keys size in bytes + */ +#define SE_KEY_SIZE 16 + +/*! + * Secure-element EUI size in bytes + */ +#define SE_EUI_SIZE 8 + +/* ST_WORKAROUND_BEGIN: Dynamic number of keys definition */ +/*! + * Number of supported crypto keys for the soft-se + */ +#if ( USE_LRWAN_1_1_X_CRYPTO == 1 ) +#if ( LORAMAC_MAX_MC_CTX > 3 ) +#define NUM_OF_KEYS 23UL +#elif ( LORAMAC_MAX_MC_CTX > 2 ) +#define NUM_OF_KEYS 20UL +#elif ( LORAMAC_MAX_MC_CTX > 1 ) +#define NUM_OF_KEYS 17UL +#else /* LORAMAC_MAX_MC_CTX == 0 */ +#define NUM_OF_KEYS 14UL +#endif /* LORAMAC_MAX_MC_CTX */ +#else /* USE_LRWAN_1_1_X_CRYPTO == 0 */ +#if ( LORAMAC_MAX_MC_CTX > 3 ) +#define NUM_OF_KEYS 19UL +#elif ( LORAMAC_MAX_MC_CTX > 2 ) +#define NUM_OF_KEYS 16UL +#elif ( LORAMAC_MAX_MC_CTX > 1 ) +#define NUM_OF_KEYS 13UL +#else /* LORAMAC_MAX_MC_CTX == 0 */ +#define NUM_OF_KEYS 10UL +#endif /* LORAMAC_MAX_MC_CTX */ +#endif /* USE_LRWAN_1_1_X_CRYPTO */ +/* ST_WORKAROUND_END */ + +/*! + * Key structure definition for the soft-se + */ +typedef struct sKey +{ + /*! + * Key identifier + */ + KeyIdentifier_t KeyID; + /*! + * Key value + */ + uint8_t KeyValue[SE_KEY_SIZE]; +#if (!defined (LORAWAN_KMS) || (LORAWAN_KMS == 0)) +#else /* LORAWAN_KMS == 1 */ + /*! + * Key object index in the above list + */ + CK_OBJECT_HANDLE Object_Index; +#endif /* LORAWAN_KMS */ +} Key_t; + +typedef struct sSecureElementNvCtx +{ + /*! + * DevEUI storage + */ + uint8_t DevEui[SE_EUI_SIZE]; + /*! + * Join EUI storage + */ + uint8_t JoinEui[SE_EUI_SIZE]; + /*! + * The key list is required for the soft-se only. All other secure-elements + * handle the storage on their own. + */ + Key_t KeyList[NUM_OF_KEYS]; + /*! + * CRC32 value of the SecureElement data structure. + */ + uint32_t Crc32; +} SecureElementNvmData_t; + + +/*! \} addtogroup SECUREELEMENT */ + +#ifdef __cplusplus +} +#endif + +#endif // __SECURE_ELEMENT_NVM_H__ diff --git a/Middlewares/Third_Party/LoRaWAN/Mac/secure-element.h b/Middlewares/Third_Party/LoRaWAN/Mac/secure-element.h index d2e81a85..227208fb 100644 --- a/Middlewares/Third_Party/LoRaWAN/Mac/secure-element.h +++ b/Middlewares/Third_Party/LoRaWAN/Mac/secure-element.h @@ -35,6 +35,16 @@ * \{ * */ +/** + ****************************************************************************** + * + * Portions COPYRIGHT 2020 STMicroelectronics + * + * @file secure-element.h + * @author MCD Application Team + * @brief Secure Element driver API + ****************************************************************************** + */ #ifndef __SECURE_ELEMENT_H__ #define __SECURE_ELEMENT_H__ @@ -45,16 +55,7 @@ extern "C" #include #include "LoRaMacCrypto.h" - -/*! - * Secure-element keys size in bytes - */ -#define SE_KEY_SIZE 16 - -/*! - * Secure-element EUI size in bytes - */ -#define SE_EUI_SIZE 8 +#include "secure-element-nvm.h" /*! * Return values. @@ -95,63 +96,62 @@ typedef enum eSecureElementStatus SECURE_ELEMENT_FAIL_ENCRYPT, }SecureElementStatus_t; +/* ST_WORKAROUND_BEGIN: Add unique ID callback as input parameter */ /*! - * Signature of callback function to be called by the Secure Element driver when the - * non volatile context have to be stored. + * \brief get the board 64 bits unique ID * + * \param [OUT] id unique */ -typedef void ( *SecureElementNvmEvent )( void ); - +typedef void ( *SecureElementGetUniqueId )(uint8_t *id); + /*! * Initialization of Secure Element driver * - * \param[IN] seNvmCtxChanged - Callback function which will be called when the - * non-volatile context have to be stored. - * \retval - Status of the operation - */ -SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged ); - -/*! - * Remove previously generated derived keys with "label" from memory - * - * \param[IN] kms_key_label - string of char to be searched in the key label - * \retval - Status of the operation + * \param[IN] nvm - Pointer to the non-volatile memory data + * structure. + * \param[IN] seGetUniqueId - Get unique ID callback + * \retval - Status of the operation */ -SecureElementStatus_t SecureElementDeleteDerivedKeys(uint8_t* kms_key_label); +SecureElementStatus_t SecureElementInit( SecureElementNvmData_t* nvm, SecureElementGetUniqueId seGetUniqueId ); +/* ST_WORKAROUND_END */ +/* ST_WORKAROUND_BEGIN: Add KMS specific functions */ /*! - * Restores the internal nvm context from passed pointer. + * Gets key item from key list. * - * \param[IN] seNvmCtx - Pointer to non-volatile module context to be restored. - * \retval - Status of the operation + * \param[IN] keyID - Key identifier + * \param[OUT] keyItem - Key item reference + * \retval - Status of the operation */ -SecureElementStatus_t SecureElementRestoreNvmCtx( void* seNvmCtx ); +SecureElementStatus_t SecureElementGetKeyByID( KeyIdentifier_t keyID, Key_t **keyItem ); /*! - * Returns a pointer to the internal non-volatile context. + * Remove previously generated dynamic keys with "label" from memory * - * \param[IN] seNvmCtxSize - Size of the module non volatile context - * \retval - Points to a structure where the module store its non volatile context + * \param[IN] keyID - Key identifier + * \param[OUT] key_label - string of char to identifying targetKeyID label + * \retval - Status of the operation */ -void* SecureElementGetNvmCtx( size_t* seNvmCtxSize ); +SecureElementStatus_t SecureElementDeleteDynamicKeys( KeyIdentifier_t keyID, uint32_t *key_label ); /*! - * Sets a key + * Sets a the KMS object handler for a given keyID (reserved to Kms) * * \param[IN] keyID - Key identifier * \param[IN] key - Key value * \retval - Status of the operation */ -SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ); +SecureElementStatus_t SecureElementSetObjHandler( KeyIdentifier_t keyID, uint32_t keyIndex ); +/* ST_WORKAROUND_END */ /*! - * Sets a the KMS object handler for a given keyID (reserved to Kms) + * Sets a key * * \param[IN] keyID - Key identifier * \param[IN] key - Key value * \retval - Status of the operation */ -SecureElementStatus_t SecureElementSetObjHandler(KeyIdentifier_t keyID, uint32_t keyIndex); +SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ); /*! * Computes a CMAC of a message using provided initial Bx block @@ -190,13 +190,12 @@ SecureElementStatus_t SecureElementAesEncrypt( uint8_t* buffer, uint16_t size, K /*! * Derives and store a key * - * \param[IN] version - LoRaWAN specification version currently in use. * \param[IN] input - Input data from which the key is derived ( 16 byte ) * \param[IN] rootKeyID - Key identifier of the root key to use to perform the derivation * \param[IN] targetKeyID - Key identifier of the key which will be derived * \retval - Status of the operation */ -SecureElementStatus_t SecureElementDeriveAndStoreKey( Version_t version, uint8_t* input, KeyIdentifier_t rootKeyID, KeyIdentifier_t targetKeyID ); +SecureElementStatus_t SecureElementDeriveAndStoreKey( uint8_t* input, KeyIdentifier_t rootKeyID, KeyIdentifier_t targetKeyID ); /*! * Process JoinAccept message. diff --git a/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.c b/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.c index 4f51af12..882f1cf0 100644 --- a/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.c +++ b/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.c @@ -1,5 +1,5 @@ /*! - * \file utilities.h + * \file utilities.c * * \brief Helper functions implementation * @@ -101,4 +101,62 @@ int8_t Nibble2HexChar( uint8_t a ) return '?'; } } -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + +uint32_t Crc32( uint8_t *buffer, uint16_t length ) +{ + // The CRC calculation follows CCITT - 0x04C11DB7 + const uint32_t reversedPolynom = 0xEDB88320; + + // CRC initial value + uint32_t crc = 0xFFFFFFFF; + + if( buffer == NULL ) + { + return 0; + } + + for( uint16_t i = 0; i < length; ++i ) + { + crc ^= ( uint32_t )buffer[i]; + for( uint16_t i = 0; i < 8; i++ ) + { + crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); + } + } + + return ~crc; +} + +uint32_t Crc32Init( void ) +{ + return 0xFFFFFFFF; +} + +uint32_t Crc32Update( uint32_t crcInit, uint8_t *buffer, uint16_t length ) +{ + // The CRC calculation follows CCITT - 0x04C11DB7 + const uint32_t reversedPolynom = 0xEDB88320; + + // CRC initial value + uint32_t crc = crcInit; + + if( buffer == NULL ) + { + return 0; + } + + for( uint16_t i = 0; i < length; ++i ) + { + crc ^= ( uint32_t )buffer[i]; + for( uint16_t i = 0; i < 8; i++ ) + { + crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); + } + } + return crc; +} + +uint32_t Crc32Finalize( uint32_t crc ) +{ + return ~crc; +} diff --git a/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.h b/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.h index 22b29b36..8f4fdedf 100644 --- a/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.h +++ b/Middlewares/Third_Party/LoRaWAN/Utilities/utilities.h @@ -27,7 +27,7 @@ * * @file utilities.h * @author MCD Application Team - * @brief Header for driver utilities.c module + * @brief Helper functions implementation ****************************************************************************** */ @@ -36,7 +36,8 @@ #define __UTILITIES_H__ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Includes ------------------------------------------------------------------*/ @@ -79,6 +80,7 @@ extern "C" { #define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) #endif +/* ST_WORKAROUND_BEGIN: Add global ceiling div macro */ /** * \brief Calculates ceiling( X / N ) * @@ -89,6 +91,7 @@ extern "C" { #ifndef DIVC #define DIVC( X, N ) ( ( ( X ) + ( N ) - 1 ) / ( N ) ) #endif +/* ST_WORKAROUND_END */ /*! * \brief Returns 2 raised to the power of n @@ -168,6 +171,45 @@ void memset1( uint8_t *dst, uint8_t value, uint16_t size ); */ int8_t Nibble2HexChar( uint8_t a ); +/*! + * \brief Computes a CCITT 32 bits CRC + * + * \param [IN] buffer Data buffer used to compute the CRC + * \param [IN] length Data buffer length + * + * \retval crc The computed buffer of length CRC + */ +uint32_t Crc32( uint8_t *buffer, uint16_t length ); + +/*! + * \brief Computes the initial value of the CCITT 32 bits CRC. This function + * can be used with functions \ref Crc32Update and \ref Crc32Finalize. + * + * \retval crc Initial crc value. + */ +uint32_t Crc32Init( void ); + +/*! + * \brief Updates the value of the crc value. + * + * \param [IN] crcInit Previous or initial crc value. + * \param [IN] buffer Data pointer. + * \param [IN] length Length of the data. + * + * \retval crc Updated crc value. + */ +uint32_t Crc32Update( uint32_t crcInit, uint8_t *buffer, uint16_t length ); + +/*! + * \brief Finalizes the crc value after the calls to \ref Crc32Update. + * + * \param [IN] crc Recent crc value. + * + * \retval crc Updated crc value. + */ +uint32_t Crc32Finalize( uint32_t crc ); + +/* ST_WORKAROUND: Moved CRITICAL_SECTION_ macro from utilities to *_conf.h header files */ #ifdef __cplusplus } #endif diff --git a/Middlewares/Third_Party/LoRaWAN/readme.md b/Middlewares/Third_Party/LoRaWAN/readme.md index 695d4d31..fd955b6d 100644 --- a/Middlewares/Third_Party/LoRaWAN/readme.md +++ b/Middlewares/Third_Party/LoRaWAN/readme.md @@ -18,25 +18,18 @@ The aim of this project is to show an example of an end-device LoRaWAN stack implementation. -This project has 3 active branches in place. +This project has 2 active branches in place. | Branch | L2 spec | RP spec | Tag/Milestone | Class | Comments | | ------------- |:-------------:|:---------:|:---------:|:---------:|:--------------| -| | [1.0.3](https://lora-alliance.org/resource-hub/lorawanr-specification-v103) | [v1.0.3revA](https://www.lora-alliance.org/resource-hub/lorawanr-regional-parameters-v103reva) | [v4.4.4](https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.4.4) | A/B/C | LoRaWAN L2 1.0.3 - **_Released_** | -| [master](https://github.com/Lora-net/LoRaMac-node/tree/master) | [1.0.3](https://lora-alliance.org/resource-hub/lorawanr-specification-v103) | [v1.0.3revA](https://www.lora-alliance.org/resource-hub/lorawanr-regional-parameters-v103reva) | [M 4.4.5](https://github.com/Lora-net/LoRaMac-node/milestone/7) | A/B/C | LoRaWAN L2 1.0.3 | -| [develop](https://github.com/Lora-net/LoRaMac-node/tree/develop) | [1.0.4](https://lora-alliance.org/resource-hub) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [M 4.5.0](https://github.com/Lora-net/LoRaMac-node/milestone/5) | A/B/C | LoRaWAN L2 1.0.4 | -| [feature/5.0.0](https://github.com/Lora-net/LoRaMac-node/tree/feature/5.0.0) | [1.0.4](https://lora-alliance.org/resource-hub) / [1.1.1](https://lora-alliance.org/resource-hub/lorawanr-specification-v11) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [M 5.0.0](https://github.com/Lora-net/LoRaMac-node/milestone/3) | A/B/C | LoRaWAN L2 1.0.4 / 1.1.1 | +| | [1.0.3](https://lora-alliance.org/resource-hub/lorawanr-specification-v103) | [v1.0.3revA](https://www.lora-alliance.org/resource-hub/lorawanr-regional-parameters-v103reva) | [v4.4.7](https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.4.7) | A/B/C | LoRaWAN L2 1.0.3 - **_Released_ (last release based on 1.0.3)** | +| [master](https://github.com/Lora-net/LoRaMac-node/tree/master) | [1.0.4](https://lora-alliance.org/resource-hub/lorawan-104-specification-package) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [v4.5.0](https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.5.0) | A/B/C | LoRaWAN L2 1.0.4 | +| [develop](https://github.com/Lora-net/LoRaMac-node/tree/develop) | [1.0.4](https://lora-alliance.org/resource-hub/lorawan-104-specification-package) / [1.1.1](https://lora-alliance.org/resource-hub/lorawanr-specification-v11) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [M 4.6.0](https://github.com/Lora-net/LoRaMac-node/milestone/3) | A/B/C | LoRaWAN L2 1.0.4 / 1.1.1 | This project fully implements ClassA, ClassB and ClassC end-device classes and it also provides SX1272/73, SX1276/77/78/79, SX1261/2 and LR1110 radio drivers. For each currently supported platform example applications are provided. -* **LoRaMac/classA**: ClassA end-device example application. - -* **LoRaMac/classB**: ClassB end-device example application. - -* **LoRaMac/classC**: ClassC end-device example application. - * **LoRaMac/fuota-test-01**: FUOTA test scenario 01 end-device example application. (Based on provided application common packages) * **LoRaMac/periodic-uplink-lpp**: ClassA/B/C end-device example application. Periodically uplinks a frame using the Cayenne LPP protocol. (Based on provided application common packages) @@ -225,7 +218,7 @@ $ make "APPLICATION":"LoRaMac", // Select LoRaMac sub project. You can choose between: - // classA, classB or classC, periodic-uplink-lpp, fuota-test-01. + // periodic-uplink-lpp, fuota-test-01. "SUB_PROJECT":"periodic-uplink-lpp", // Switch for Class B support of LoRaMac: @@ -326,7 +319,7 @@ $ make "APPLICATION":"ping-pong", // Select LoRaMac sub project. You can choose between: - // classA, classB or classC, periodic-uplink-lpp, fuota-test-01. + // periodic-uplink-lpp, fuota-test-01. "SUB_PROJECT":"periodic-uplink-lpp", // Switch for Class B support of LoRaMac: diff --git a/Middlewares/Third_Party/LoRaWAN/st_readme.txt b/Middlewares/Third_Party/LoRaWAN/st_readme.txt index 838a909c..6c422247 100644 --- a/Middlewares/Third_Party/LoRaWAN/st_readme.txt +++ b/Middlewares/Third_Party/LoRaWAN/st_readme.txt @@ -20,6 +20,26 @@ ****************************************************************************** @endverbatim +### V2.3.0/18-May-2021 ### +=============================== + + Implements LoRa Mac from Semtech/StackForce develop branch (18-Jan-2021 commits, version 4.4.7) + + + SecureElementDeleteDerivedKeys dynamic implementation in using KMS APIs + + + Cleanup NVM key attributes with KMS default values definition + + + Printable Keys (Root and derived) with KEY_EXTRACTABLE + + + Remove GCCv9 compiler warnings + + + Fix SetAppEUI/SetDevEUI functions + + + Add LinkCheckReq and DeviceTimeReq support + + + Fragmentation processing move to application layer + + + Release Notes update + ### V2.2.1/2-Oct-2020 ### =============================== + Multiple tools write to the same file' if AES + LoRaWAN + option .c/.h diff --git a/Middlewares/Third_Party/Sigfox/Release_notes.html b/Middlewares/Third_Party/Sigfox/Release_notes.html deleted file mode 100644 index cd849b01..00000000 --- a/Middlewares/Third_Party/Sigfox/Release_notes.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - Release Notes for STM32WLxx Sigfox Middleware - - - - - -
    -
    -
    -
    -
    -

    Release Notes for STM32WLxx Sigfox Middleware

    -

    Copyright © 2020 STMicroelectronics
    -

    - -
    -
    -
    -

    License

    -

    This software component is licensed by ST under Ultimate Liberty license SLA0044, the “License”;

    -

    You may not use this file except in compliance with the License.

    -

    You may obtain a copy of the License at: SLA0044

    -

    Sigfox specific license is also applicable at: Sigfox License

    -

    Purpose

    -

    This Middlewares provides the Sigfox Middleware for the stm32wlxx products. This covers

    -
      -
    • STM32WLxx devices
    • -
    -

    This driver is composed of 4 directories:

    -
      -
    • Crypto

    • -
    • Monarch

    • -
    • SigfoxLib

    • -
    • SigfoxLibTest
    • -
    -
    -
    -

    Update History

    -
    - -
    -

    Main Changes

    -

    Multiple tools write to the same file' if AES + Sigfox + option .c/.h

    -

    Release Notes update

    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • Monarch: V2.0.0 (STMicroelectronics Patent)
    • -
    • SigfoxLib: V2.8.1
    • -
    • SigfoxLibTest: V0.6.0
    • -
    -
    -
    -
    - -
    -

    Main Changes

    -

    Updated SigfoxLib

    -

    Release Notes update

    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • Monarch: V2.0.0 (STMicroelectronics Patent)
    • -
    • SigfoxLib: V2.8.1 => NEW
    • -
    • SigfoxLibTest: V0.6.0
    • -
    -
    -
    -
    - -
    -

    Main Changes

    -

    encrypted_sigfox_data update for KMS

    -

    SIGFOX_API_init() interface function definition

    -

    /Templates directory creation

    -

    Release Notes update

    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • Monarch: V2.0.0 (STMicroelectronics Patent)
    • -
    • SigfoxLib: V2.8.0
    • -
    • SigfoxLibTest: V0.6.0
    • -
    -
    -
    -
    - -
    -

    Main Changes

    -

    Release Notes information update

    -


    -

    -
    -
    -
    - -
    -

    Main Changes

    -

    Release Notes formatting update

    -


    -

    -
    -
    -
    - -
    -

    Main Changes

    -

    All libraries: eabi compatible

    -

    Update Sigfox library versions to:

    -

    - SFX_ADDON_RFP_V0.6.0_SE_FDL_MON.a

    -

    - SFX_LIB_V2.8.0_SE_FDL_MON.a => RC1 to RC7 supported

    -

    Monarch library addition: Sgfx-Monarch-V2.0.0 (STMicroelectronics Patent)

    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • Monarch: V2.0.0 (STMicroelectronics Patent) => NEW
    • -
    • SigfoxLib: V2.8.0 => NEW
    • -
    • SigfoxLibTest: V0.6.0 => NEW
    • -
    -


    -

    -
    -
    -
    - -
    -

    Main Changes

    -

    Cleanup of licenses

    -
    -
    -
    - -
    -

    Main Changes

    -

    Middleware for STM32Cube solution including v2.6.1 sigfox library

    -
     merged with Monarch algorithm 
    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • SigfoxLib: V2.6.1 => NEW
    • -
    • SigfoxLibTest: V0.6.0
      -
    • -
    -
    -
    -
    - -
    -

    Main Changes

    -

    Middleware for STM32Cube solution including v2.3.1 sigfox library

    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • SigfoxLib: V2.3.1 => NEW
    • -
    • SigfoxLibTest: V0.6.0
      -
    • -
    -
    -
    -
    - -
    -

    Main Changes

    -

    Middleware for STM32Cube solution including v2.0.2 sigfox library

    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • SigfoxLib: V2.0.2 => NEW
    • -
    • SigfoxLibTest: V0.6.0
      -
    • -
    -
    -
    -
    - -
    -

    Main Changes

    -

    First version

    -

    Middleware for STM32Cube solution including v1.8.9 sigfox library

    -

    Version of embedded Sigfox libraries:

    -
      -
    • Crypto : V1.0.0
    • -
    • SigfoxLib: V1.8.9 => NEW
    • -
    • SigfoxLibTest: V0.6.0
      -
    • -
    -
    -
    -
    -
    -
    -

    For complete documentation on STM32, visit: [www.st.com/stm32]

    -This release note uses up to date web standards and, for this reason, should not be opened with Internet Explorer but preferably with popular browsers such as Google Chrome, Mozilla Firefox, Opera or Microsoft Edge. -
    - - diff --git a/Middlewares/Third_Party/Sigfox/_htmresc/mini-st.css b/Middlewares/Third_Party/Sigfox/_htmresc/mini-st.css deleted file mode 100644 index eb41d56c..00000000 --- a/Middlewares/Third_Party/Sigfox/_htmresc/mini-st.css +++ /dev/null @@ -1,1700 +0,0 @@ -@charset "UTF-8"; -/* - Flavor name: Default (mini-default) - Author: Angelos Chalaris (chalarangelo@gmail.com) - Maintainers: Angelos Chalaris - mini.css version: v3.0.0-alpha.3 -*/ -/* - Browsers resets and base typography. -*/ -/* Core module CSS variable definitions */ -:root { - --fore-color: #111; - --secondary-fore-color: #444; - --back-color: #f8f8f8; - --secondary-back-color: #f0f0f0; - --blockquote-color: #f57c00; - --pre-color: #1565c0; - --border-color: #aaa; - --secondary-border-color: #ddd; - --heading-ratio: 1.19; - --universal-margin: 0.5rem; - --universal-padding: 0.125rem; - --universal-border-radius: 0.125rem; - --a-link-color: #0277bd; - --a-visited-color: #01579b; } - -html { - font-size: 14px; } - -a, b, del, em, i, ins, q, span, strong, u { - font-size: 1em; } - -html, * { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif; - line-height: 1.4; - -webkit-text-size-adjust: 100%; } - -* { - font-size: 1rem; } - -body { - margin: 0; - color: var(--fore-color); - background: var(--back-color); } - -details { - display: block; } - -summary { - display: list-item; } - -abbr[title] { - border-bottom: none; - text-decoration: underline dotted; } - -input { - overflow: visible; } - -img { - max-width: 100%; - height: auto; } - -h1, h2, h3, h4, h5, h6 { - line-height: 1.2; - margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); - font-weight: 500; } - h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { - color: var(--secondary-fore-color); - display: block; - margin-top: -0.25rem; } - -h1 { - font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } - -h2 { - font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio); ); - background: var(--mark-back-color); - font-weight: 600; - padding: 0.1em 0.5em 0.2em 0.5em; - color: var(--mark-fore-color); } - -h3 { - font-size: calc(1rem * var(--heading-ratio)); - padding-left: calc(2 * var(--universal-margin)); - /* background: var(--border-color); */ - } - -h4 { - font-size: 1rem;); - padding-left: calc(4 * var(--universal-margin)); } - -h5 { - font-size: 1rem; } - -h6 { - font-size: calc(1rem / var(--heading-ratio)); } - -p { - margin: var(--universal-margin); } - -ol, ul { - margin: var(--universal-margin); - padding-left: calc(6 * var(--universal-margin)); } - -b, strong { - font-weight: 700; } - -hr { - box-sizing: content-box; - border: 0; - line-height: 1.25em; - margin: var(--universal-margin); - height: 0.0625rem; - background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } - -blockquote { - display: block; - position: relative; - font-style: italic; - color: var(--secondary-fore-color); - margin: var(--universal-margin); - padding: calc(3 * var(--universal-padding)); - border: 0.0625rem solid var(--secondary-border-color); - border-left: 0.375rem solid var(--blockquote-color); - border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } - blockquote:before { - position: absolute; - top: calc(0rem - var(--universal-padding)); - left: 0; - font-family: sans-serif; - font-size: 3rem; - font-weight: 700; - content: "\201c"; - color: var(--blockquote-color); } - blockquote[cite]:after { - font-style: normal; - font-size: 0.75em; - font-weight: 700; - content: "\a— " attr(cite); - white-space: pre; } - -code, kbd, pre, samp { - font-family: Menlo, Consolas, monospace; - font-size: 0.85em; } - -code { - background: var(--secondary-back-color); - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - -kbd { - background: var(--fore-color); - color: var(--back-color); - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - -pre { - overflow: auto; - background: var(--secondary-back-color); - padding: calc(1.5 * var(--universal-padding)); - margin: var(--universal-margin); - border: 0.0625rem solid var(--secondary-border-color); - border-left: 0.25rem solid var(--pre-color); - border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } - -sup, sub, code, kbd { - line-height: 0; - position: relative; - vertical-align: baseline; } - -small, sup, sub, figcaption { - font-size: 0.75em; } - -sup { - top: -0.5em; } - -sub { - bottom: -0.25em; } - -figure { - margin: var(--universal-margin); } - -figcaption { - color: var(--secondary-fore-color); } - -a { - text-decoration: none; } - a:link { - color: var(--a-link-color); } - a:visited { - color: var(--a-visited-color); } - a:hover, a:focus { - text-decoration: underline; } - -/* - Definitions for the grid system, cards and containers. -*/ -.container { - margin: 0 auto; - padding: 0 calc(1.5 * var(--universal-padding)); } - -.row { - box-sizing: border-box; - display: flex; - flex: 0 1 auto; - flex-flow: row wrap; } - -.col-sm, -[class^='col-sm-'], -[class^='col-sm-offset-'], -.row[class*='cols-sm-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - -.col-sm, -.row.cols-sm > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - -.col-sm-1, -.row.cols-sm-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - -.col-sm-offset-0 { - margin-left: 0; } - -.col-sm-2, -.row.cols-sm-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - -.col-sm-offset-1 { - margin-left: 8.3333333333%; } - -.col-sm-3, -.row.cols-sm-3 > * { - max-width: 25%; - flex-basis: 25%; } - -.col-sm-offset-2 { - margin-left: 16.6666666667%; } - -.col-sm-4, -.row.cols-sm-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - -.col-sm-offset-3 { - margin-left: 25%; } - -.col-sm-5, -.row.cols-sm-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - -.col-sm-offset-4 { - margin-left: 33.3333333333%; } - -.col-sm-6, -.row.cols-sm-6 > * { - max-width: 50%; - flex-basis: 50%; } - -.col-sm-offset-5 { - margin-left: 41.6666666667%; } - -.col-sm-7, -.row.cols-sm-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - -.col-sm-offset-6 { - margin-left: 50%; } - -.col-sm-8, -.row.cols-sm-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - -.col-sm-offset-7 { - margin-left: 58.3333333333%; } - -.col-sm-9, -.row.cols-sm-9 > * { - max-width: 75%; - flex-basis: 75%; } - -.col-sm-offset-8 { - margin-left: 66.6666666667%; } - -.col-sm-10, -.row.cols-sm-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - -.col-sm-offset-9 { - margin-left: 75%; } - -.col-sm-11, -.row.cols-sm-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - -.col-sm-offset-10 { - margin-left: 83.3333333333%; } - -.col-sm-12, -.row.cols-sm-12 > * { - max-width: 100%; - flex-basis: 100%; } - -.col-sm-offset-11 { - margin-left: 91.6666666667%; } - -.col-sm-normal { - order: initial; } - -.col-sm-first { - order: -999; } - -.col-sm-last { - order: 999; } - -@media screen and (min-width: 500px) { - .col-md, - [class^='col-md-'], - [class^='col-md-offset-'], - .row[class*='cols-md-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - - .col-md, - .row.cols-md > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - - .col-md-1, - .row.cols-md-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - - .col-md-offset-0 { - margin-left: 0; } - - .col-md-2, - .row.cols-md-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - - .col-md-offset-1 { - margin-left: 8.3333333333%; } - - .col-md-3, - .row.cols-md-3 > * { - max-width: 25%; - flex-basis: 25%; } - - .col-md-offset-2 { - margin-left: 16.6666666667%; } - - .col-md-4, - .row.cols-md-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - - .col-md-offset-3 { - margin-left: 25%; } - - .col-md-5, - .row.cols-md-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - - .col-md-offset-4 { - margin-left: 33.3333333333%; } - - .col-md-6, - .row.cols-md-6 > * { - max-width: 50%; - flex-basis: 50%; } - - .col-md-offset-5 { - margin-left: 41.6666666667%; } - - .col-md-7, - .row.cols-md-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - - .col-md-offset-6 { - margin-left: 50%; } - - .col-md-8, - .row.cols-md-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - - .col-md-offset-7 { - margin-left: 58.3333333333%; } - - .col-md-9, - .row.cols-md-9 > * { - max-width: 75%; - flex-basis: 75%; } - - .col-md-offset-8 { - margin-left: 66.6666666667%; } - - .col-md-10, - .row.cols-md-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - - .col-md-offset-9 { - margin-left: 75%; } - - .col-md-11, - .row.cols-md-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - - .col-md-offset-10 { - margin-left: 83.3333333333%; } - - .col-md-12, - .row.cols-md-12 > * { - max-width: 100%; - flex-basis: 100%; } - - .col-md-offset-11 { - margin-left: 91.6666666667%; } - - .col-md-normal { - order: initial; } - - .col-md-first { - order: -999; } - - .col-md-last { - order: 999; } } -@media screen and (min-width: 1280px) { - .col-lg, - [class^='col-lg-'], - [class^='col-lg-offset-'], - .row[class*='cols-lg-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - - .col-lg, - .row.cols-lg > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - - .col-lg-1, - .row.cols-lg-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - - .col-lg-offset-0 { - margin-left: 0; } - - .col-lg-2, - .row.cols-lg-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - - .col-lg-offset-1 { - margin-left: 8.3333333333%; } - - .col-lg-3, - .row.cols-lg-3 > * { - max-width: 25%; - flex-basis: 25%; } - - .col-lg-offset-2 { - margin-left: 16.6666666667%; } - - .col-lg-4, - .row.cols-lg-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - - .col-lg-offset-3 { - margin-left: 25%; } - - .col-lg-5, - .row.cols-lg-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - - .col-lg-offset-4 { - margin-left: 33.3333333333%; } - - .col-lg-6, - .row.cols-lg-6 > * { - max-width: 50%; - flex-basis: 50%; } - - .col-lg-offset-5 { - margin-left: 41.6666666667%; } - - .col-lg-7, - .row.cols-lg-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - - .col-lg-offset-6 { - margin-left: 50%; } - - .col-lg-8, - .row.cols-lg-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - - .col-lg-offset-7 { - margin-left: 58.3333333333%; } - - .col-lg-9, - .row.cols-lg-9 > * { - max-width: 75%; - flex-basis: 75%; } - - .col-lg-offset-8 { - margin-left: 66.6666666667%; } - - .col-lg-10, - .row.cols-lg-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - - .col-lg-offset-9 { - margin-left: 75%; } - - .col-lg-11, - .row.cols-lg-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - - .col-lg-offset-10 { - margin-left: 83.3333333333%; } - - .col-lg-12, - .row.cols-lg-12 > * { - max-width: 100%; - flex-basis: 100%; } - - .col-lg-offset-11 { - margin-left: 91.6666666667%; } - - .col-lg-normal { - order: initial; } - - .col-lg-first { - order: -999; } - - .col-lg-last { - order: 999; } } -/* Card component CSS variable definitions */ -:root { - --card-back-color: #f8f8f8; - --card-fore-color: #111; - --card-border-color: #ddd; } - -.card { - display: flex; - flex-direction: column; - justify-content: space-between; - align-self: center; - position: relative; - width: 100%; - background: var(--card-back-color); - color: var(--card-fore-color); - border: 0.0625rem solid var(--card-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); - overflow: hidden; } - @media screen and (min-width: 320px) { - .card { - max-width: 320px; } } - .card > .sectione { - background: var(--card-back-color); - color: var(--card-fore-color); - box-sizing: border-box; - margin: 0; - border: 0; - border-radius: 0; - border-bottom: 0.0625rem solid var(--card-border-color); - padding: var(--universal-padding); - width: 100%; } - .card > .sectione.media { - height: 200px; - padding: 0; - -o-object-fit: cover; - object-fit: cover; } - .card > .sectione:last-child { - border-bottom: 0; } - -/* - Custom elements for card elements. -*/ -@media screen and (min-width: 240px) { - .card.small { - max-width: 240px; } } -@media screen and (min-width: 480px) { - .card.large { - max-width: 480px; } } -.card.fluid { - max-width: 100%; - width: auto; } - -.card.warning { -/* --card-back-color: #ffca28; */ - --card-back-color: #e5b8b7; - --card-border-color: #e8b825; } - -.card.error { - --card-back-color: #b71c1c; - --card-fore-color: #f8f8f8; - --card-border-color: #a71a1a; } - -.card > .sectione.dark { - --card-back-color: #e0e0e0; } - -.card > .sectione.double-padded { - padding: calc(1.5 * var(--universal-padding)); } - -/* - Definitions for forms and input elements. -*/ -/* Input_control module CSS variable definitions */ -:root { - --form-back-color: #f0f0f0; - --form-fore-color: #111; - --form-border-color: #ddd; - --input-back-color: #f8f8f8; - --input-fore-color: #111; - --input-border-color: #ddd; - --input-focus-color: #0288d1; - --input-invalid-color: #d32f2f; - --button-back-color: #e2e2e2; - --button-hover-back-color: #dcdcdc; - --button-fore-color: #212121; - --button-border-color: transparent; - --button-hover-border-color: transparent; - --button-group-border-color: rgba(124, 124, 124, 0.54); } - -form { - background: var(--form-back-color); - color: var(--form-fore-color); - border: 0.0625rem solid var(--form-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); - padding: calc(2 * var(--universal-padding)) var(--universal-padding); } - -fieldset { - border: 0.0625rem solid var(--form-border-color); - border-radius: var(--universal-border-radius); - margin: calc(var(--universal-margin) / 4); - padding: var(--universal-padding); } - -legend { - box-sizing: border-box; - display: table; - max-width: 100%; - white-space: normal; - font-weight: 700; - padding: calc(var(--universal-padding) / 2); } - -label { - padding: calc(var(--universal-padding) / 2) var(--universal-padding); } - -.input-group { - display: inline-block; } - .input-group.fluid { - display: flex; - align-items: center; - justify-content: center; } - .input-group.fluid > input { - max-width: 100%; - flex-grow: 1; - flex-basis: 0px; } - @media screen and (max-width: 499px) { - .input-group.fluid { - align-items: stretch; - flex-direction: column; } } - .input-group.vertical { - display: flex; - align-items: stretch; - flex-direction: column; } - .input-group.vertical > input { - max-width: 100%; - flex-grow: 1; - flex-basis: 0px; } - -[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; } - -[type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; } - -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; } - -input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], -[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { - box-sizing: border-box; - background: var(--input-back-color); - color: var(--input-fore-color); - border: 0.0625rem solid var(--input-border-color); - border-radius: var(--universal-border-radius); - margin: calc(var(--universal-margin) / 2); - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } - -input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { - border-color: var(--input-focus-color); - box-shadow: none; } -input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { - border-color: var(--input-invalid-color); - box-shadow: none; } -input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { - background: var(--secondary-back-color); } - -select { - max-width: 100%; } - -option { - overflow: hidden; - text-overflow: ellipsis; } - -[type="checkbox"], [type="radio"] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - position: relative; - height: calc(1rem + var(--universal-padding) / 2); - width: calc(1rem + var(--universal-padding) / 2); - vertical-align: text-bottom; - padding: 0; - flex-basis: calc(1rem + var(--universal-padding) / 2) !important; - flex-grow: 0 !important; } - [type="checkbox"]:checked:before, [type="radio"]:checked:before { - position: absolute; } - -[type="checkbox"]:checked:before { - content: '\2713'; - font-family: sans-serif; - font-size: calc(1rem + var(--universal-padding) / 2); - top: calc(0rem - var(--universal-padding)); - left: calc(var(--universal-padding) / 4); } - -[type="radio"] { - border-radius: 100%; } - [type="radio"]:checked:before { - border-radius: 100%; - content: ''; - top: calc(0.0625rem + var(--universal-padding) / 2); - left: calc(0.0625rem + var(--universal-padding) / 2); - background: var(--input-fore-color); - width: 0.5rem; - height: 0.5rem; } - -:placeholder-shown { - color: var(--input-fore-color); } - -::-ms-placeholder { - color: var(--input-fore-color); - opacity: 0.54; } - -button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; } - -button, html [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; } - -button { - overflow: visible; - text-transform: none; } - -button, [type="button"], [type="submit"], [type="reset"], -a.button, label.button, .button, -a[role="button"], label[role="button"], [role="button"] { - display: inline-block; - background: var(--button-back-color); - color: var(--button-fore-color); - border: 0.0625rem solid var(--button-border-color); - border-radius: var(--universal-border-radius); - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); - margin: var(--universal-margin); - text-decoration: none; - cursor: pointer; - transition: background 0.3s; } - button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, - a.button:hover, - a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, - a[role="button"]:hover, - a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { - background: var(--button-hover-back-color); - border-color: var(--button-hover-border-color); } - -input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { - cursor: not-allowed; - opacity: 0.75; } - -.button-group { - display: flex; - border: 0.0625rem solid var(--button-group-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); } - .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { - margin: 0; - max-width: 100%; - flex: 1 1 auto; - text-align: center; - border: 0; - border-radius: 0; - box-shadow: none; } - .button-group > :not(:first-child) { - border-left: 0.0625rem solid var(--button-group-border-color); } - @media screen and (max-width: 499px) { - .button-group { - flex-direction: column; } - .button-group > :not(:first-child) { - border: 0; - border-top: 0.0625rem solid var(--button-group-border-color); } } - -/* - Custom elements for forms and input elements. -*/ -button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { - --button-back-color: #1976d2; - --button-fore-color: #f8f8f8; } - button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { - --button-hover-back-color: #1565c0; } - -button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { - --button-back-color: #d32f2f; - --button-fore-color: #f8f8f8; } - button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { - --button-hover-back-color: #c62828; } - -button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { - --button-back-color: #308732; - --button-fore-color: #f8f8f8; } - button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { - --button-hover-back-color: #277529; } - -button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { - --button-back-color: #212121; - --button-fore-color: #f8f8f8; } - button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { - --button-hover-back-color: #111; } - -button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { - padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); - margin: var(--universal-margin); } - -button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { - padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); - margin: var(--universal-margin); } - -/* - Definitions for navigation elements. -*/ -/* Navigation module CSS variable definitions */ -:root { - --header-back-color: #f8f8f8; - --header-hover-back-color: #f0f0f0; - --header-fore-color: #444; - --header-border-color: #ddd; - --nav-back-color: #f8f8f8; - --nav-hover-back-color: #f0f0f0; - --nav-fore-color: #444; - --nav-border-color: #ddd; - --nav-link-color: #0277bd; - --footer-fore-color: #444; - --footer-back-color: #f8f8f8; - --footer-border-color: #ddd; - --footer-link-color: #0277bd; - --drawer-back-color: #f8f8f8; - --drawer-hover-back-color: #f0f0f0; - --drawer-border-color: #ddd; - --drawer-close-color: #444; } - -header { - height: 3.1875rem; - background: var(--header-back-color); - color: var(--header-fore-color); - border-bottom: 0.0625rem solid var(--header-border-color); - padding: calc(var(--universal-padding) / 4) 0; - white-space: nowrap; - overflow-x: auto; - overflow-y: hidden; } - header.row { - box-sizing: content-box; } - header .logo { - color: var(--header-fore-color); - font-size: 1.75rem; - padding: var(--universal-padding) calc(2 * var(--universal-padding)); - text-decoration: none; } - header button, header [type="button"], header .button, header [role="button"] { - box-sizing: border-box; - position: relative; - top: calc(0rem - var(--universal-padding) / 4); - height: calc(3.1875rem + var(--universal-padding) / 2); - background: var(--header-back-color); - line-height: calc(3.1875rem - var(--universal-padding) * 1.5); - text-align: center; - color: var(--header-fore-color); - border: 0; - border-radius: 0; - margin: 0; - text-transform: uppercase; } - header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { - background: var(--header-hover-back-color); } - -nav { - background: var(--nav-back-color); - color: var(--nav-fore-color); - border: 0.0625rem solid var(--nav-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); } - nav * { - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } - nav a, nav a:visited { - display: block; - color: var(--nav-link-color); - border-radius: var(--universal-border-radius); - transition: background 0.3s; } - nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { - text-decoration: none; - background: var(--nav-hover-back-color); } - nav .sublink-1 { - position: relative; - margin-left: calc(2 * var(--universal-padding)); } - nav .sublink-1:before { - position: absolute; - left: calc(var(--universal-padding) - 1 * var(--universal-padding)); - top: -0.0625rem; - content: ''; - height: 100%; - border: 0.0625rem solid var(--nav-border-color); - border-left: 0; } - nav .sublink-2 { - position: relative; - margin-left: calc(4 * var(--universal-padding)); } - nav .sublink-2:before { - position: absolute; - left: calc(var(--universal-padding) - 3 * var(--universal-padding)); - top: -0.0625rem; - content: ''; - height: 100%; - border: 0.0625rem solid var(--nav-border-color); - border-left: 0; } - -footer { - background: var(--footer-back-color); - color: var(--footer-fore-color); - border-top: 0.0625rem solid var(--footer-border-color); - padding: calc(2 * var(--universal-padding)) var(--universal-padding); - font-size: 0.875rem; } - footer a, footer a:visited { - color: var(--footer-link-color); } - -header.sticky { - position: -webkit-sticky; - position: sticky; - z-index: 1101; - top: 0; } - -footer.sticky { - position: -webkit-sticky; - position: sticky; - z-index: 1101; - bottom: 0; } - -.drawer-toggle:before { - display: inline-block; - position: relative; - vertical-align: bottom; - content: '\00a0\2261\00a0'; - font-family: sans-serif; - font-size: 1.5em; } -@media screen and (min-width: 500px) { - .drawer-toggle:not(.persistent) { - display: none; } } - -[type="checkbox"].drawer { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - [type="checkbox"].drawer + * { - display: block; - box-sizing: border-box; - position: fixed; - top: 0; - width: 320px; - height: 100vh; - overflow-y: auto; - background: var(--drawer-back-color); - border: 0.0625rem solid var(--drawer-border-color); - border-radius: 0; - margin: 0; - z-index: 1110; - right: -320px; - transition: right 0.3s; } - [type="checkbox"].drawer + * .drawer-close { - position: absolute; - top: var(--universal-margin); - right: var(--universal-margin); - z-index: 1111; - width: 2rem; - height: 2rem; - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - margin: 0; - cursor: pointer; - transition: background 0.3s; } - [type="checkbox"].drawer + * .drawer-close:before { - display: block; - content: '\00D7'; - color: var(--drawer-close-color); - position: relative; - font-family: sans-serif; - font-size: 2rem; - line-height: 1; - text-align: center; } - [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { - background: var(--drawer-hover-back-color); } - @media screen and (max-width: 320px) { - [type="checkbox"].drawer + * { - width: 100%; } } - [type="checkbox"].drawer:checked + * { - right: 0; } - @media screen and (min-width: 500px) { - [type="checkbox"].drawer:not(.persistent) + * { - position: static; - height: 100%; - z-index: 1100; } - [type="checkbox"].drawer:not(.persistent) + * .drawer-close { - display: none; } } - -/* - Definitions for the responsive table component. -*/ -/* Table module CSS variable definitions. */ -:root { - --table-border-color: #aaa; - --table-border-separator-color: #666; - --table-head-back-color: #e6e6e6; - --table-head-fore-color: #111; - --table-body-back-color: #f8f8f8; - --table-body-fore-color: #111; - --table-body-alt-back-color: #eee; } - -table { - border-collapse: separate; - border-spacing: 0; - : margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); - display: flex; - flex: 0 1 auto; - flex-flow: row wrap; - padding: var(--universal-padding); - padding-top: 0; - margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); } - table caption { - font-size: 1.25 * rem; - margin: calc(2 * var(--universal-margin)) 0; - max-width: 100%; - flex: 0 0 100%; - text-align: left;} - table thead, table tbody { - display: flex; - flex-flow: row wrap; - border: 0.0625rem solid var(--table-border-color); } - table thead { - z-index: 999; - border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; - border-bottom: 0.0625rem solid var(--table-border-separator-color); } - table tbody { - border-top: 0; - margin-top: calc(0 - var(--universal-margin)); - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - table tr { - display: flex; - padding: 0; } - table th, table td { - padding: calc(0.5 * var(--universal-padding)); - font-size: 0.9rem; } - table th { - text-align: left; - background: var(--table-head-back-color); - color: var(--table-head-fore-color); } - table td { - background: var(--table-body-back-color); - color: var(--table-body-fore-color); - border-top: 0.0625rem solid var(--table-border-color); } - -table:not(.horizontal) { - overflow: auto; - max-height: 850px; } - table:not(.horizontal) thead, table:not(.horizontal) tbody { - max-width: 100%; - flex: 0 0 100%; } - table:not(.horizontal) tr { - flex-flow: row wrap; - flex: 0 0 100%; } - table:not(.horizontal) th, table:not(.horizontal) td { - flex: 1 0 0%; - overflow: hidden; - text-overflow: ellipsis; } - table:not(.horizontal) thead { - position: sticky; - top: 0; } - table:not(.horizontal) tbody tr:first-child td { - border-top: 0; } - -table.horizontal { - border: 0; } - table.horizontal thead, table.horizontal tbody { - border: 0; - flex-flow: row nowrap; } - table.horizontal tbody { - overflow: auto; - justify-content: space-between; - flex: 1 0 0; - margin-left: calc( 4 * var(--universal-margin)); - padding-bottom: calc(var(--universal-padding) / 4); } - table.horizontal tr { - flex-direction: column; - flex: 1 0 auto; } - table.horizontal th, table.horizontal td { - width: 100%; - border: 0; - border-bottom: 0.0625rem solid var(--table-border-color); } - table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { - border-top: 0; } - table.horizontal th { - text-align: right; - border-left: 0.0625rem solid var(--table-border-color); - border-right: 0.0625rem solid var(--table-border-separator-color); } - table.horizontal thead tr:first-child { - padding-left: 0; } - table.horizontal th:first-child, table.horizontal td:first-child { - border-top: 0.0625rem solid var(--table-border-color); } - table.horizontal tbody tr:last-child td { - border-right: 0.0625rem solid var(--table-border-color); } - table.horizontal tbody tr:last-child td:first-child { - border-top-right-radius: 0.25rem; } - table.horizontal tbody tr:last-child td:last-child { - border-bottom-right-radius: 0.25rem; } - table.horizontal thead tr:first-child th:first-child { - border-top-left-radius: 0.25rem; } - table.horizontal thead tr:first-child th:last-child { - border-bottom-left-radius: 0.25rem; } - -@media screen and (max-width: 499px) { - table, table.horizontal { - border-collapse: collapse; - border: 0; - width: 100%; - display: table; } - table thead, table th, table.horizontal thead, table.horizontal th { - border: 0; - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - table tbody, table.horizontal tbody { - border: 0; - display: table-row-group; } - table tr, table.horizontal tr { - display: block; - border: 0.0625rem solid var(--table-border-color); - border-radius: var(--universal-border-radius); - background: #fafafa; - padding: var(--universal-padding); - margin: var(--universal-margin); - margin-bottom: calc(2 * var(--universal-margin)); } - table th, table td, table.horizontal th, table.horizontal td { - width: auto; } - table td, table.horizontal td { - display: block; - border: 0; - text-align: right; } - table td:before, table.horizontal td:before { - content: attr(data-label); - float: left; - font-weight: 600; } - table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { - border-top: 0; } - table tbody tr:last-child td, table.horizontal tbody tr:last-child td { - border-right: 0; } } -:root { - --table-body-alt-back-color: #eee; } - -table tr:nth-of-type(2n) > td { - background: var(--table-body-alt-back-color); } - -@media screen and (max-width: 500px) { - table tr:nth-of-type(2n) { - background: var(--table-body-alt-back-color); } } -:root { - --table-body-hover-back-color: #90caf9; } - -table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { - background: var(--table-body-hover-back-color); } - -@media screen and (max-width: 500px) { - table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { - background: var(--table-body-hover-back-color); } } -/* - Definitions for contextual background elements, toasts and tooltips. -*/ -/* Contextual module CSS variable definitions */ -:root { - --mark-back-color: #0277bd; - --mark-fore-color: #fafafa; } - -mark { - background: var(--mark-back-color); - color: var(--mark-fore-color); - font-size: 0.95em; - line-height: 1em; - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - mark.inline-block { - display: inline-block; - font-size: 1em; - line-height: 1.5; - padding: calc(var(--universal-padding) / 2) var(--universal-padding); } - -:root { - --toast-back-color: #424242; - --toast-fore-color: #fafafa; } - -.toast { - position: fixed; - bottom: calc(var(--universal-margin) * 3); - left: 50%; - transform: translate(-50%, -50%); - z-index: 1111; - color: var(--toast-fore-color); - background: var(--toast-back-color); - border-radius: calc(var(--universal-border-radius) * 16); - padding: var(--universal-padding) calc(var(--universal-padding) * 3); } - -:root { - --tooltip-back-color: #212121; - --tooltip-fore-color: #fafafa; } - -.tooltip { - position: relative; - display: inline-block; } - .tooltip:before, .tooltip:after { - position: absolute; - opacity: 0; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); - transition: all 0.3s; - z-index: 1010; - left: 50%; } - .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { - bottom: 75%; } - .tooltip.bottom:before, .tooltip.bottom:after { - top: 75%; } - .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { - opacity: 1; - clip: auto; - -webkit-clip-path: inset(0%); - clip-path: inset(0%); } - .tooltip:before { - content: ''; - background: transparent; - border: var(--universal-margin) solid transparent; - left: calc(50% - var(--universal-margin)); } - .tooltip:not(.bottom):before { - border-top-color: #212121; } - .tooltip.bottom:before { - border-bottom-color: #212121; } - .tooltip:after { - content: attr(aria-label); - color: var(--tooltip-fore-color); - background: var(--tooltip-back-color); - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - white-space: nowrap; - transform: translateX(-50%); } - .tooltip:not(.bottom):after { - margin-bottom: calc(2 * var(--universal-margin)); } - .tooltip.bottom:after { - margin-top: calc(2 * var(--universal-margin)); } - -:root { - --modal-overlay-color: rgba(0, 0, 0, 0.45); - --modal-close-color: #444; - --modal-close-hover-color: #f0f0f0; } - -[type="checkbox"].modal { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - [type="checkbox"].modal + div { - position: fixed; - top: 0; - left: 0; - display: none; - width: 100vw; - height: 100vh; - background: var(--modal-overlay-color); } - [type="checkbox"].modal + div .card { - margin: 0 auto; - max-height: 50vh; - overflow: auto; } - [type="checkbox"].modal + div .card .modal-close { - position: absolute; - top: 0; - right: 0; - width: 1.75rem; - height: 1.75rem; - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - margin: 0; - cursor: pointer; - transition: background 0.3s; } - [type="checkbox"].modal + div .card .modal-close:before { - display: block; - content: '\00D7'; - color: var(--modal-close-color); - position: relative; - font-family: sans-serif; - font-size: 1.75rem; - line-height: 1; - text-align: center; } - [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { - background: var(--modal-close-hover-color); } - [type="checkbox"].modal:checked + div { - display: flex; - flex: 0 1 auto; - z-index: 1200; } - [type="checkbox"].modal:checked + div .card .modal-close { - z-index: 1211; } - -:root { - --collapse-label-back-color: #e8e8e8; - --collapse-label-fore-color: #212121; - --collapse-label-hover-back-color: #f0f0f0; - --collapse-selected-label-back-color: #ececec; - --collapse-border-color: #ddd; - --collapse-content-back-color: #fafafa; - --collapse-selected-label-border-color: #0277bd; } - -.collapse { - width: calc(100% - 2 * var(--universal-margin)); - opacity: 1; - display: flex; - flex-direction: column; - margin: var(--universal-margin); - border-radius: var(--universal-border-radius); } - .collapse > [type="radio"], .collapse > [type="checkbox"] { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - .collapse > label { - flex-grow: 1; - display: inline-block; - height: 1.5rem; - cursor: pointer; - transition: background 0.3s; - color: var(--collapse-label-fore-color); - background: var(--collapse-label-back-color); - border: 0.0625rem solid var(--collapse-border-color); - padding: calc(1.5 * var(--universal-padding)); } - .collapse > label:hover, .collapse > label:focus { - background: var(--collapse-label-hover-back-color); } - .collapse > label + div { - flex-basis: auto; - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); - transition: max-height 0.3s; - max-height: 1px; } - .collapse > :checked + label { - background: var(--collapse-selected-label-back-color); - border-bottom-color: var(--collapse-selected-label-border-color); } - .collapse > :checked + label + div { - box-sizing: border-box; - position: relative; - width: 100%; - height: auto; - overflow: auto; - margin: 0; - background: var(--collapse-content-back-color); - border: 0.0625rem solid var(--collapse-border-color); - border-top: 0; - padding: var(--universal-padding); - clip: auto; - -webkit-clip-path: inset(0%); - clip-path: inset(0%); - max-height: 850px; } - .collapse > label:not(:first-of-type) { - border-top: 0; } - .collapse > label:first-of-type { - border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } - .collapse > label:last-of-type:not(:first-of-type) { - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - .collapse > label:last-of-type:first-of-type { - border-radius: var(--universal-border-radius); } - .collapse > :checked:last-of-type:not(:first-of-type) + label { - border-radius: 0; } - .collapse > :checked:last-of-type + label + div { - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - -/* - Custom elements for contextual background elements, toasts and tooltips. -*/ -mark.secondary { - --mark-back-color: #d32f2f; } - -mark.tertiary { - --mark-back-color: #308732; } - -mark.tag { - padding: calc(var(--universal-padding)/2) var(--universal-padding); - border-radius: 1em; } - -/* - Definitions for progress elements and spinners. -*/ -/* Progress module CSS variable definitions */ -:root { - --progress-back-color: #ddd; - --progress-fore-color: #555; } - -progress { - display: block; - vertical-align: baseline; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - height: 0.75rem; - width: calc(100% - 2 * var(--universal-margin)); - margin: var(--universal-margin); - border: 0; - border-radius: calc(2 * var(--universal-border-radius)); - background: var(--progress-back-color); - color: var(--progress-fore-color); } - progress::-webkit-progress-value { - background: var(--progress-fore-color); - border-top-left-radius: calc(2 * var(--universal-border-radius)); - border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } - progress::-webkit-progress-bar { - background: var(--progress-back-color); } - progress::-moz-progress-bar { - background: var(--progress-fore-color); - border-top-left-radius: calc(2 * var(--universal-border-radius)); - border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } - progress[value="1000"]::-webkit-progress-value { - border-radius: calc(2 * var(--universal-border-radius)); } - progress[value="1000"]::-moz-progress-bar { - border-radius: calc(2 * var(--universal-border-radius)); } - progress.inline { - display: inline-block; - vertical-align: middle; - width: 60%; } - -:root { - --spinner-back-color: #ddd; - --spinner-fore-color: #555; } - -@keyframes spinner-donut-anim { - 0% { - transform: rotate(0deg); } - 100% { - transform: rotate(360deg); } } -.spinner { - display: inline-block; - margin: var(--universal-margin); - border: 0.25rem solid var(--spinner-back-color); - border-left: 0.25rem solid var(--spinner-fore-color); - border-radius: 50%; - width: 1.25rem; - height: 1.25rem; - animation: spinner-donut-anim 1.2s linear infinite; } - -/* - Custom elements for progress bars and spinners. -*/ -progress.primary { - --progress-fore-color: #1976d2; } - -progress.secondary { - --progress-fore-color: #d32f2f; } - -progress.tertiary { - --progress-fore-color: #308732; } - -.spinner.primary { - --spinner-fore-color: #1976d2; } - -.spinner.secondary { - --spinner-fore-color: #d32f2f; } - -.spinner.tertiary { - --spinner-fore-color: #308732; } - -/* - Definitions for icons - powered by Feather (https://feathericons.com/). -*/ -span[class^='icon-'] { - display: inline-block; - height: 1em; - width: 1em; - vertical-align: -0.125em; - background-size: contain; - margin: 0 calc(var(--universal-margin) / 4); } - span[class^='icon-'].secondary { - -webkit-filter: invert(25%); - filter: invert(25%); } - span[class^='icon-'].inverse { - -webkit-filter: invert(100%); - filter: invert(100%); } - -span.icon-alert { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-bookmark { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-calendar { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-credit { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-edit { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } -span.icon-link { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-help { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-home { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } -span.icon-info { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-lock { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-mail { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } -span.icon-location { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } -span.icon-phone { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-rss { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } -span.icon-search { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-settings { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-share { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-cart { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-upload { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-user { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } - -/* - Definitions for utilities and helper classes. -*/ -/* Utility module CSS variable definitions */ -:root { - --generic-border-color: rgba(0, 0, 0, 0.3); - --generic-box-shadow: 0 0.25rem 0.25rem 0 rgba(0, 0, 0, 0.125), 0 0.125rem 0.125rem -0.125rem rgba(0, 0, 0, 0.25); } - -.hidden { - display: none !important; } - -.visually-hidden { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } - -.bordered { - border: 0.0625rem solid var(--generic-border-color) !important; } - -.rounded { - border-radius: var(--universal-border-radius) !important; } - -.circular { - border-radius: 50% !important; } - -.shadowed { - box-shadow: var(--generic-box-shadow) !important; } - -.responsive-margin { - margin: calc(var(--universal-margin) / 4) !important; } - @media screen and (min-width: 500px) { - .responsive-margin { - margin: calc(var(--universal-margin) / 2) !important; } } - @media screen and (min-width: 1280px) { - .responsive-margin { - margin: var(--universal-margin) !important; } } - -.responsive-padding { - padding: calc(var(--universal-padding) / 4) !important; } - @media screen and (min-width: 500px) { - .responsive-padding { - padding: calc(var(--universal-padding) / 2) !important; } } - @media screen and (min-width: 1280px) { - .responsive-padding { - padding: var(--universal-padding) !important; } } - -@media screen and (max-width: 499px) { - .hidden-sm { - display: none !important; } } -@media screen and (min-width: 500px) and (max-width: 1279px) { - .hidden-md { - display: none !important; } } -@media screen and (min-width: 1280px) { - .hidden-lg { - display: none !important; } } -@media screen and (max-width: 499px) { - .visually-hidden-sm { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } -@media screen and (min-width: 500px) and (max-width: 1279px) { - .visually-hidden-md { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } -@media screen and (min-width: 1280px) { - .visually-hidden-lg { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } - -/*# sourceMappingURL=mini-default.css.map */ diff --git a/Middlewares/Third_Party/Sigfox/_htmresc/st_logo.png b/Middlewares/Third_Party/Sigfox/_htmresc/st_logo.png deleted file mode 100644 index 8b80057f..00000000 Binary files a/Middlewares/Third_Party/Sigfox/_htmresc/st_logo.png and /dev/null differ diff --git a/Middlewares/Third_Party/SubGHz_Phy/LICENSE.txt b/Middlewares/Third_Party/SubGHz_Phy/LICENSE.txt deleted file mode 100644 index d6dfb1b8..00000000 --- a/Middlewares/Third_Party/SubGHz_Phy/LICENSE.txt +++ /dev/null @@ -1,25 +0,0 @@ ---- Revised BSD License --- -Copyright (c) 2013, SEMTECH S.A. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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. - * Neither the name of the Semtech corporation 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 SEMTECH S.A. 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. \ No newline at end of file diff --git a/Middlewares/Third_Party/SubGHz_Phy/Release_notes.html b/Middlewares/Third_Party/SubGHz_Phy/Release_notes.html index 24a00d81..1f9eda44 100644 --- a/Middlewares/Third_Party/SubGHz_Phy/Release_notes.html +++ b/Middlewares/Third_Party/SubGHz_Phy/Release_notes.html @@ -11,26 +11,24 @@ span.underline{text-decoration: underline;} div.column{display: inline-block; vertical-align: top; width: 50%;} - + +
    -
    -

    Release Notes for STM32WLxx SubGHz Physical Layer Middleware

    -

    Copyright © 2020 STMicroelectronics
    +

    Copyright © 2021 STMicroelectronics

    - +
    -
    -

    License

    -

    This software component is licensed by ST under BSD 3-Clause, the “License”; You may not use this component except in compliance with the License. You may obtain a copy of the License at: BSD 3-Clause

    +

    Licensed by ST under BSD 3-Clause license (the "License"). You may not use this component except in compliance with the License. You may obtain a copy of the License at:

    +

    https://opensource.org/licenses/BSD-3-Clause

    Purpose

    This Middlewares provides the SubGHz Physical Layer for the stm32wlxx products. This covers

      @@ -41,10 +39,31 @@

      Purpose

      Update History

      - +

      Main Changes

      -

      First release

      +

      fix: SMPS drive level init

      +

      fix: GENERIC_BPSK in RadioSetTxGenericConfig function (test mode)

      +

      fix: MODEM_BPSK is not handled in RadioSetModem in radio.c

      +

      feature: add cfo calculation

      +

      fix: reduce interrupt scope to minimize privilege stack code execution

      +

      feature:add long packet in radio_fw

      +

      feature: Support IBM whitening by firmware radio_fw

      +

      fix: Channel Activity Detection: antenna switch set in rx mode

      +

      fix: Deadlock of WL RF driver

      +

      fix: PingPong RxErrors when SF12, BW500, CR 4/8

      +

      feature: move GetFskBandwidthRegValue in radio_driver

      +

      fix: Incorrect LoRa PER Results

      +

      feature: align to LoRaWAN Semtech stack v4.4.7 integration - Radio Part

      +


      +

      +
      +
      +
      + +
      +

      Main Changes

      +

      First Release


      @@ -52,7 +71,7 @@

      First release

      -

      For complete documentation on STM32, visit: [www.st.com/stm32]

      +

      For complete documentation on STM32, visit: [www.st.com/stm32]

      This release note uses up to date web standards and, for this reason, should not be opened with Internet Explorer but preferably with popular browsers such as Google Chrome, Mozilla Firefox, Opera or Microsoft Edge.
      diff --git a/Middlewares/Third_Party/SubGHz_Phy/_htmresc/mini-st.css b/Middlewares/Third_Party/SubGHz_Phy/_htmresc/mini-st.css deleted file mode 100644 index eb41d56c..00000000 --- a/Middlewares/Third_Party/SubGHz_Phy/_htmresc/mini-st.css +++ /dev/null @@ -1,1700 +0,0 @@ -@charset "UTF-8"; -/* - Flavor name: Default (mini-default) - Author: Angelos Chalaris (chalarangelo@gmail.com) - Maintainers: Angelos Chalaris - mini.css version: v3.0.0-alpha.3 -*/ -/* - Browsers resets and base typography. -*/ -/* Core module CSS variable definitions */ -:root { - --fore-color: #111; - --secondary-fore-color: #444; - --back-color: #f8f8f8; - --secondary-back-color: #f0f0f0; - --blockquote-color: #f57c00; - --pre-color: #1565c0; - --border-color: #aaa; - --secondary-border-color: #ddd; - --heading-ratio: 1.19; - --universal-margin: 0.5rem; - --universal-padding: 0.125rem; - --universal-border-radius: 0.125rem; - --a-link-color: #0277bd; - --a-visited-color: #01579b; } - -html { - font-size: 14px; } - -a, b, del, em, i, ins, q, span, strong, u { - font-size: 1em; } - -html, * { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif; - line-height: 1.4; - -webkit-text-size-adjust: 100%; } - -* { - font-size: 1rem; } - -body { - margin: 0; - color: var(--fore-color); - background: var(--back-color); } - -details { - display: block; } - -summary { - display: list-item; } - -abbr[title] { - border-bottom: none; - text-decoration: underline dotted; } - -input { - overflow: visible; } - -img { - max-width: 100%; - height: auto; } - -h1, h2, h3, h4, h5, h6 { - line-height: 1.2; - margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); - font-weight: 500; } - h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { - color: var(--secondary-fore-color); - display: block; - margin-top: -0.25rem; } - -h1 { - font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } - -h2 { - font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio); ); - background: var(--mark-back-color); - font-weight: 600; - padding: 0.1em 0.5em 0.2em 0.5em; - color: var(--mark-fore-color); } - -h3 { - font-size: calc(1rem * var(--heading-ratio)); - padding-left: calc(2 * var(--universal-margin)); - /* background: var(--border-color); */ - } - -h4 { - font-size: 1rem;); - padding-left: calc(4 * var(--universal-margin)); } - -h5 { - font-size: 1rem; } - -h6 { - font-size: calc(1rem / var(--heading-ratio)); } - -p { - margin: var(--universal-margin); } - -ol, ul { - margin: var(--universal-margin); - padding-left: calc(6 * var(--universal-margin)); } - -b, strong { - font-weight: 700; } - -hr { - box-sizing: content-box; - border: 0; - line-height: 1.25em; - margin: var(--universal-margin); - height: 0.0625rem; - background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } - -blockquote { - display: block; - position: relative; - font-style: italic; - color: var(--secondary-fore-color); - margin: var(--universal-margin); - padding: calc(3 * var(--universal-padding)); - border: 0.0625rem solid var(--secondary-border-color); - border-left: 0.375rem solid var(--blockquote-color); - border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } - blockquote:before { - position: absolute; - top: calc(0rem - var(--universal-padding)); - left: 0; - font-family: sans-serif; - font-size: 3rem; - font-weight: 700; - content: "\201c"; - color: var(--blockquote-color); } - blockquote[cite]:after { - font-style: normal; - font-size: 0.75em; - font-weight: 700; - content: "\a— " attr(cite); - white-space: pre; } - -code, kbd, pre, samp { - font-family: Menlo, Consolas, monospace; - font-size: 0.85em; } - -code { - background: var(--secondary-back-color); - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - -kbd { - background: var(--fore-color); - color: var(--back-color); - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - -pre { - overflow: auto; - background: var(--secondary-back-color); - padding: calc(1.5 * var(--universal-padding)); - margin: var(--universal-margin); - border: 0.0625rem solid var(--secondary-border-color); - border-left: 0.25rem solid var(--pre-color); - border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } - -sup, sub, code, kbd { - line-height: 0; - position: relative; - vertical-align: baseline; } - -small, sup, sub, figcaption { - font-size: 0.75em; } - -sup { - top: -0.5em; } - -sub { - bottom: -0.25em; } - -figure { - margin: var(--universal-margin); } - -figcaption { - color: var(--secondary-fore-color); } - -a { - text-decoration: none; } - a:link { - color: var(--a-link-color); } - a:visited { - color: var(--a-visited-color); } - a:hover, a:focus { - text-decoration: underline; } - -/* - Definitions for the grid system, cards and containers. -*/ -.container { - margin: 0 auto; - padding: 0 calc(1.5 * var(--universal-padding)); } - -.row { - box-sizing: border-box; - display: flex; - flex: 0 1 auto; - flex-flow: row wrap; } - -.col-sm, -[class^='col-sm-'], -[class^='col-sm-offset-'], -.row[class*='cols-sm-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - -.col-sm, -.row.cols-sm > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - -.col-sm-1, -.row.cols-sm-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - -.col-sm-offset-0 { - margin-left: 0; } - -.col-sm-2, -.row.cols-sm-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - -.col-sm-offset-1 { - margin-left: 8.3333333333%; } - -.col-sm-3, -.row.cols-sm-3 > * { - max-width: 25%; - flex-basis: 25%; } - -.col-sm-offset-2 { - margin-left: 16.6666666667%; } - -.col-sm-4, -.row.cols-sm-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - -.col-sm-offset-3 { - margin-left: 25%; } - -.col-sm-5, -.row.cols-sm-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - -.col-sm-offset-4 { - margin-left: 33.3333333333%; } - -.col-sm-6, -.row.cols-sm-6 > * { - max-width: 50%; - flex-basis: 50%; } - -.col-sm-offset-5 { - margin-left: 41.6666666667%; } - -.col-sm-7, -.row.cols-sm-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - -.col-sm-offset-6 { - margin-left: 50%; } - -.col-sm-8, -.row.cols-sm-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - -.col-sm-offset-7 { - margin-left: 58.3333333333%; } - -.col-sm-9, -.row.cols-sm-9 > * { - max-width: 75%; - flex-basis: 75%; } - -.col-sm-offset-8 { - margin-left: 66.6666666667%; } - -.col-sm-10, -.row.cols-sm-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - -.col-sm-offset-9 { - margin-left: 75%; } - -.col-sm-11, -.row.cols-sm-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - -.col-sm-offset-10 { - margin-left: 83.3333333333%; } - -.col-sm-12, -.row.cols-sm-12 > * { - max-width: 100%; - flex-basis: 100%; } - -.col-sm-offset-11 { - margin-left: 91.6666666667%; } - -.col-sm-normal { - order: initial; } - -.col-sm-first { - order: -999; } - -.col-sm-last { - order: 999; } - -@media screen and (min-width: 500px) { - .col-md, - [class^='col-md-'], - [class^='col-md-offset-'], - .row[class*='cols-md-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - - .col-md, - .row.cols-md > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - - .col-md-1, - .row.cols-md-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - - .col-md-offset-0 { - margin-left: 0; } - - .col-md-2, - .row.cols-md-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - - .col-md-offset-1 { - margin-left: 8.3333333333%; } - - .col-md-3, - .row.cols-md-3 > * { - max-width: 25%; - flex-basis: 25%; } - - .col-md-offset-2 { - margin-left: 16.6666666667%; } - - .col-md-4, - .row.cols-md-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - - .col-md-offset-3 { - margin-left: 25%; } - - .col-md-5, - .row.cols-md-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - - .col-md-offset-4 { - margin-left: 33.3333333333%; } - - .col-md-6, - .row.cols-md-6 > * { - max-width: 50%; - flex-basis: 50%; } - - .col-md-offset-5 { - margin-left: 41.6666666667%; } - - .col-md-7, - .row.cols-md-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - - .col-md-offset-6 { - margin-left: 50%; } - - .col-md-8, - .row.cols-md-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - - .col-md-offset-7 { - margin-left: 58.3333333333%; } - - .col-md-9, - .row.cols-md-9 > * { - max-width: 75%; - flex-basis: 75%; } - - .col-md-offset-8 { - margin-left: 66.6666666667%; } - - .col-md-10, - .row.cols-md-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - - .col-md-offset-9 { - margin-left: 75%; } - - .col-md-11, - .row.cols-md-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - - .col-md-offset-10 { - margin-left: 83.3333333333%; } - - .col-md-12, - .row.cols-md-12 > * { - max-width: 100%; - flex-basis: 100%; } - - .col-md-offset-11 { - margin-left: 91.6666666667%; } - - .col-md-normal { - order: initial; } - - .col-md-first { - order: -999; } - - .col-md-last { - order: 999; } } -@media screen and (min-width: 1280px) { - .col-lg, - [class^='col-lg-'], - [class^='col-lg-offset-'], - .row[class*='cols-lg-'] > * { - box-sizing: border-box; - flex: 0 0 auto; - padding: 0 calc(var(--universal-padding) / 2); } - - .col-lg, - .row.cols-lg > * { - max-width: 100%; - flex-grow: 1; - flex-basis: 0; } - - .col-lg-1, - .row.cols-lg-1 > * { - max-width: 8.3333333333%; - flex-basis: 8.3333333333%; } - - .col-lg-offset-0 { - margin-left: 0; } - - .col-lg-2, - .row.cols-lg-2 > * { - max-width: 16.6666666667%; - flex-basis: 16.6666666667%; } - - .col-lg-offset-1 { - margin-left: 8.3333333333%; } - - .col-lg-3, - .row.cols-lg-3 > * { - max-width: 25%; - flex-basis: 25%; } - - .col-lg-offset-2 { - margin-left: 16.6666666667%; } - - .col-lg-4, - .row.cols-lg-4 > * { - max-width: 33.3333333333%; - flex-basis: 33.3333333333%; } - - .col-lg-offset-3 { - margin-left: 25%; } - - .col-lg-5, - .row.cols-lg-5 > * { - max-width: 41.6666666667%; - flex-basis: 41.6666666667%; } - - .col-lg-offset-4 { - margin-left: 33.3333333333%; } - - .col-lg-6, - .row.cols-lg-6 > * { - max-width: 50%; - flex-basis: 50%; } - - .col-lg-offset-5 { - margin-left: 41.6666666667%; } - - .col-lg-7, - .row.cols-lg-7 > * { - max-width: 58.3333333333%; - flex-basis: 58.3333333333%; } - - .col-lg-offset-6 { - margin-left: 50%; } - - .col-lg-8, - .row.cols-lg-8 > * { - max-width: 66.6666666667%; - flex-basis: 66.6666666667%; } - - .col-lg-offset-7 { - margin-left: 58.3333333333%; } - - .col-lg-9, - .row.cols-lg-9 > * { - max-width: 75%; - flex-basis: 75%; } - - .col-lg-offset-8 { - margin-left: 66.6666666667%; } - - .col-lg-10, - .row.cols-lg-10 > * { - max-width: 83.3333333333%; - flex-basis: 83.3333333333%; } - - .col-lg-offset-9 { - margin-left: 75%; } - - .col-lg-11, - .row.cols-lg-11 > * { - max-width: 91.6666666667%; - flex-basis: 91.6666666667%; } - - .col-lg-offset-10 { - margin-left: 83.3333333333%; } - - .col-lg-12, - .row.cols-lg-12 > * { - max-width: 100%; - flex-basis: 100%; } - - .col-lg-offset-11 { - margin-left: 91.6666666667%; } - - .col-lg-normal { - order: initial; } - - .col-lg-first { - order: -999; } - - .col-lg-last { - order: 999; } } -/* Card component CSS variable definitions */ -:root { - --card-back-color: #f8f8f8; - --card-fore-color: #111; - --card-border-color: #ddd; } - -.card { - display: flex; - flex-direction: column; - justify-content: space-between; - align-self: center; - position: relative; - width: 100%; - background: var(--card-back-color); - color: var(--card-fore-color); - border: 0.0625rem solid var(--card-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); - overflow: hidden; } - @media screen and (min-width: 320px) { - .card { - max-width: 320px; } } - .card > .sectione { - background: var(--card-back-color); - color: var(--card-fore-color); - box-sizing: border-box; - margin: 0; - border: 0; - border-radius: 0; - border-bottom: 0.0625rem solid var(--card-border-color); - padding: var(--universal-padding); - width: 100%; } - .card > .sectione.media { - height: 200px; - padding: 0; - -o-object-fit: cover; - object-fit: cover; } - .card > .sectione:last-child { - border-bottom: 0; } - -/* - Custom elements for card elements. -*/ -@media screen and (min-width: 240px) { - .card.small { - max-width: 240px; } } -@media screen and (min-width: 480px) { - .card.large { - max-width: 480px; } } -.card.fluid { - max-width: 100%; - width: auto; } - -.card.warning { -/* --card-back-color: #ffca28; */ - --card-back-color: #e5b8b7; - --card-border-color: #e8b825; } - -.card.error { - --card-back-color: #b71c1c; - --card-fore-color: #f8f8f8; - --card-border-color: #a71a1a; } - -.card > .sectione.dark { - --card-back-color: #e0e0e0; } - -.card > .sectione.double-padded { - padding: calc(1.5 * var(--universal-padding)); } - -/* - Definitions for forms and input elements. -*/ -/* Input_control module CSS variable definitions */ -:root { - --form-back-color: #f0f0f0; - --form-fore-color: #111; - --form-border-color: #ddd; - --input-back-color: #f8f8f8; - --input-fore-color: #111; - --input-border-color: #ddd; - --input-focus-color: #0288d1; - --input-invalid-color: #d32f2f; - --button-back-color: #e2e2e2; - --button-hover-back-color: #dcdcdc; - --button-fore-color: #212121; - --button-border-color: transparent; - --button-hover-border-color: transparent; - --button-group-border-color: rgba(124, 124, 124, 0.54); } - -form { - background: var(--form-back-color); - color: var(--form-fore-color); - border: 0.0625rem solid var(--form-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); - padding: calc(2 * var(--universal-padding)) var(--universal-padding); } - -fieldset { - border: 0.0625rem solid var(--form-border-color); - border-radius: var(--universal-border-radius); - margin: calc(var(--universal-margin) / 4); - padding: var(--universal-padding); } - -legend { - box-sizing: border-box; - display: table; - max-width: 100%; - white-space: normal; - font-weight: 700; - padding: calc(var(--universal-padding) / 2); } - -label { - padding: calc(var(--universal-padding) / 2) var(--universal-padding); } - -.input-group { - display: inline-block; } - .input-group.fluid { - display: flex; - align-items: center; - justify-content: center; } - .input-group.fluid > input { - max-width: 100%; - flex-grow: 1; - flex-basis: 0px; } - @media screen and (max-width: 499px) { - .input-group.fluid { - align-items: stretch; - flex-direction: column; } } - .input-group.vertical { - display: flex; - align-items: stretch; - flex-direction: column; } - .input-group.vertical > input { - max-width: 100%; - flex-grow: 1; - flex-basis: 0px; } - -[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { - height: auto; } - -[type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; } - -[type="search"]::-webkit-search-cancel-button, -[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; } - -input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], -[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { - box-sizing: border-box; - background: var(--input-back-color); - color: var(--input-fore-color); - border: 0.0625rem solid var(--input-border-color); - border-radius: var(--universal-border-radius); - margin: calc(var(--universal-margin) / 2); - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } - -input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { - border-color: var(--input-focus-color); - box-shadow: none; } -input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { - border-color: var(--input-invalid-color); - box-shadow: none; } -input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { - background: var(--secondary-back-color); } - -select { - max-width: 100%; } - -option { - overflow: hidden; - text-overflow: ellipsis; } - -[type="checkbox"], [type="radio"] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - position: relative; - height: calc(1rem + var(--universal-padding) / 2); - width: calc(1rem + var(--universal-padding) / 2); - vertical-align: text-bottom; - padding: 0; - flex-basis: calc(1rem + var(--universal-padding) / 2) !important; - flex-grow: 0 !important; } - [type="checkbox"]:checked:before, [type="radio"]:checked:before { - position: absolute; } - -[type="checkbox"]:checked:before { - content: '\2713'; - font-family: sans-serif; - font-size: calc(1rem + var(--universal-padding) / 2); - top: calc(0rem - var(--universal-padding)); - left: calc(var(--universal-padding) / 4); } - -[type="radio"] { - border-radius: 100%; } - [type="radio"]:checked:before { - border-radius: 100%; - content: ''; - top: calc(0.0625rem + var(--universal-padding) / 2); - left: calc(0.0625rem + var(--universal-padding) / 2); - background: var(--input-fore-color); - width: 0.5rem; - height: 0.5rem; } - -:placeholder-shown { - color: var(--input-fore-color); } - -::-ms-placeholder { - color: var(--input-fore-color); - opacity: 0.54; } - -button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { - border-style: none; - padding: 0; } - -button, html [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; } - -button { - overflow: visible; - text-transform: none; } - -button, [type="button"], [type="submit"], [type="reset"], -a.button, label.button, .button, -a[role="button"], label[role="button"], [role="button"] { - display: inline-block; - background: var(--button-back-color); - color: var(--button-fore-color); - border: 0.0625rem solid var(--button-border-color); - border-radius: var(--universal-border-radius); - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); - margin: var(--universal-margin); - text-decoration: none; - cursor: pointer; - transition: background 0.3s; } - button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, - a.button:hover, - a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, - a[role="button"]:hover, - a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { - background: var(--button-hover-back-color); - border-color: var(--button-hover-border-color); } - -input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { - cursor: not-allowed; - opacity: 0.75; } - -.button-group { - display: flex; - border: 0.0625rem solid var(--button-group-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); } - .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { - margin: 0; - max-width: 100%; - flex: 1 1 auto; - text-align: center; - border: 0; - border-radius: 0; - box-shadow: none; } - .button-group > :not(:first-child) { - border-left: 0.0625rem solid var(--button-group-border-color); } - @media screen and (max-width: 499px) { - .button-group { - flex-direction: column; } - .button-group > :not(:first-child) { - border: 0; - border-top: 0.0625rem solid var(--button-group-border-color); } } - -/* - Custom elements for forms and input elements. -*/ -button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { - --button-back-color: #1976d2; - --button-fore-color: #f8f8f8; } - button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { - --button-hover-back-color: #1565c0; } - -button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { - --button-back-color: #d32f2f; - --button-fore-color: #f8f8f8; } - button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { - --button-hover-back-color: #c62828; } - -button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { - --button-back-color: #308732; - --button-fore-color: #f8f8f8; } - button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { - --button-hover-back-color: #277529; } - -button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { - --button-back-color: #212121; - --button-fore-color: #f8f8f8; } - button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { - --button-hover-back-color: #111; } - -button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { - padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); - margin: var(--universal-margin); } - -button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { - padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); - margin: var(--universal-margin); } - -/* - Definitions for navigation elements. -*/ -/* Navigation module CSS variable definitions */ -:root { - --header-back-color: #f8f8f8; - --header-hover-back-color: #f0f0f0; - --header-fore-color: #444; - --header-border-color: #ddd; - --nav-back-color: #f8f8f8; - --nav-hover-back-color: #f0f0f0; - --nav-fore-color: #444; - --nav-border-color: #ddd; - --nav-link-color: #0277bd; - --footer-fore-color: #444; - --footer-back-color: #f8f8f8; - --footer-border-color: #ddd; - --footer-link-color: #0277bd; - --drawer-back-color: #f8f8f8; - --drawer-hover-back-color: #f0f0f0; - --drawer-border-color: #ddd; - --drawer-close-color: #444; } - -header { - height: 3.1875rem; - background: var(--header-back-color); - color: var(--header-fore-color); - border-bottom: 0.0625rem solid var(--header-border-color); - padding: calc(var(--universal-padding) / 4) 0; - white-space: nowrap; - overflow-x: auto; - overflow-y: hidden; } - header.row { - box-sizing: content-box; } - header .logo { - color: var(--header-fore-color); - font-size: 1.75rem; - padding: var(--universal-padding) calc(2 * var(--universal-padding)); - text-decoration: none; } - header button, header [type="button"], header .button, header [role="button"] { - box-sizing: border-box; - position: relative; - top: calc(0rem - var(--universal-padding) / 4); - height: calc(3.1875rem + var(--universal-padding) / 2); - background: var(--header-back-color); - line-height: calc(3.1875rem - var(--universal-padding) * 1.5); - text-align: center; - color: var(--header-fore-color); - border: 0; - border-radius: 0; - margin: 0; - text-transform: uppercase; } - header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { - background: var(--header-hover-back-color); } - -nav { - background: var(--nav-back-color); - color: var(--nav-fore-color); - border: 0.0625rem solid var(--nav-border-color); - border-radius: var(--universal-border-radius); - margin: var(--universal-margin); } - nav * { - padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } - nav a, nav a:visited { - display: block; - color: var(--nav-link-color); - border-radius: var(--universal-border-radius); - transition: background 0.3s; } - nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { - text-decoration: none; - background: var(--nav-hover-back-color); } - nav .sublink-1 { - position: relative; - margin-left: calc(2 * var(--universal-padding)); } - nav .sublink-1:before { - position: absolute; - left: calc(var(--universal-padding) - 1 * var(--universal-padding)); - top: -0.0625rem; - content: ''; - height: 100%; - border: 0.0625rem solid var(--nav-border-color); - border-left: 0; } - nav .sublink-2 { - position: relative; - margin-left: calc(4 * var(--universal-padding)); } - nav .sublink-2:before { - position: absolute; - left: calc(var(--universal-padding) - 3 * var(--universal-padding)); - top: -0.0625rem; - content: ''; - height: 100%; - border: 0.0625rem solid var(--nav-border-color); - border-left: 0; } - -footer { - background: var(--footer-back-color); - color: var(--footer-fore-color); - border-top: 0.0625rem solid var(--footer-border-color); - padding: calc(2 * var(--universal-padding)) var(--universal-padding); - font-size: 0.875rem; } - footer a, footer a:visited { - color: var(--footer-link-color); } - -header.sticky { - position: -webkit-sticky; - position: sticky; - z-index: 1101; - top: 0; } - -footer.sticky { - position: -webkit-sticky; - position: sticky; - z-index: 1101; - bottom: 0; } - -.drawer-toggle:before { - display: inline-block; - position: relative; - vertical-align: bottom; - content: '\00a0\2261\00a0'; - font-family: sans-serif; - font-size: 1.5em; } -@media screen and (min-width: 500px) { - .drawer-toggle:not(.persistent) { - display: none; } } - -[type="checkbox"].drawer { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - [type="checkbox"].drawer + * { - display: block; - box-sizing: border-box; - position: fixed; - top: 0; - width: 320px; - height: 100vh; - overflow-y: auto; - background: var(--drawer-back-color); - border: 0.0625rem solid var(--drawer-border-color); - border-radius: 0; - margin: 0; - z-index: 1110; - right: -320px; - transition: right 0.3s; } - [type="checkbox"].drawer + * .drawer-close { - position: absolute; - top: var(--universal-margin); - right: var(--universal-margin); - z-index: 1111; - width: 2rem; - height: 2rem; - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - margin: 0; - cursor: pointer; - transition: background 0.3s; } - [type="checkbox"].drawer + * .drawer-close:before { - display: block; - content: '\00D7'; - color: var(--drawer-close-color); - position: relative; - font-family: sans-serif; - font-size: 2rem; - line-height: 1; - text-align: center; } - [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { - background: var(--drawer-hover-back-color); } - @media screen and (max-width: 320px) { - [type="checkbox"].drawer + * { - width: 100%; } } - [type="checkbox"].drawer:checked + * { - right: 0; } - @media screen and (min-width: 500px) { - [type="checkbox"].drawer:not(.persistent) + * { - position: static; - height: 100%; - z-index: 1100; } - [type="checkbox"].drawer:not(.persistent) + * .drawer-close { - display: none; } } - -/* - Definitions for the responsive table component. -*/ -/* Table module CSS variable definitions. */ -:root { - --table-border-color: #aaa; - --table-border-separator-color: #666; - --table-head-back-color: #e6e6e6; - --table-head-fore-color: #111; - --table-body-back-color: #f8f8f8; - --table-body-fore-color: #111; - --table-body-alt-back-color: #eee; } - -table { - border-collapse: separate; - border-spacing: 0; - : margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); - display: flex; - flex: 0 1 auto; - flex-flow: row wrap; - padding: var(--universal-padding); - padding-top: 0; - margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); } - table caption { - font-size: 1.25 * rem; - margin: calc(2 * var(--universal-margin)) 0; - max-width: 100%; - flex: 0 0 100%; - text-align: left;} - table thead, table tbody { - display: flex; - flex-flow: row wrap; - border: 0.0625rem solid var(--table-border-color); } - table thead { - z-index: 999; - border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; - border-bottom: 0.0625rem solid var(--table-border-separator-color); } - table tbody { - border-top: 0; - margin-top: calc(0 - var(--universal-margin)); - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - table tr { - display: flex; - padding: 0; } - table th, table td { - padding: calc(0.5 * var(--universal-padding)); - font-size: 0.9rem; } - table th { - text-align: left; - background: var(--table-head-back-color); - color: var(--table-head-fore-color); } - table td { - background: var(--table-body-back-color); - color: var(--table-body-fore-color); - border-top: 0.0625rem solid var(--table-border-color); } - -table:not(.horizontal) { - overflow: auto; - max-height: 850px; } - table:not(.horizontal) thead, table:not(.horizontal) tbody { - max-width: 100%; - flex: 0 0 100%; } - table:not(.horizontal) tr { - flex-flow: row wrap; - flex: 0 0 100%; } - table:not(.horizontal) th, table:not(.horizontal) td { - flex: 1 0 0%; - overflow: hidden; - text-overflow: ellipsis; } - table:not(.horizontal) thead { - position: sticky; - top: 0; } - table:not(.horizontal) tbody tr:first-child td { - border-top: 0; } - -table.horizontal { - border: 0; } - table.horizontal thead, table.horizontal tbody { - border: 0; - flex-flow: row nowrap; } - table.horizontal tbody { - overflow: auto; - justify-content: space-between; - flex: 1 0 0; - margin-left: calc( 4 * var(--universal-margin)); - padding-bottom: calc(var(--universal-padding) / 4); } - table.horizontal tr { - flex-direction: column; - flex: 1 0 auto; } - table.horizontal th, table.horizontal td { - width: 100%; - border: 0; - border-bottom: 0.0625rem solid var(--table-border-color); } - table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { - border-top: 0; } - table.horizontal th { - text-align: right; - border-left: 0.0625rem solid var(--table-border-color); - border-right: 0.0625rem solid var(--table-border-separator-color); } - table.horizontal thead tr:first-child { - padding-left: 0; } - table.horizontal th:first-child, table.horizontal td:first-child { - border-top: 0.0625rem solid var(--table-border-color); } - table.horizontal tbody tr:last-child td { - border-right: 0.0625rem solid var(--table-border-color); } - table.horizontal tbody tr:last-child td:first-child { - border-top-right-radius: 0.25rem; } - table.horizontal tbody tr:last-child td:last-child { - border-bottom-right-radius: 0.25rem; } - table.horizontal thead tr:first-child th:first-child { - border-top-left-radius: 0.25rem; } - table.horizontal thead tr:first-child th:last-child { - border-bottom-left-radius: 0.25rem; } - -@media screen and (max-width: 499px) { - table, table.horizontal { - border-collapse: collapse; - border: 0; - width: 100%; - display: table; } - table thead, table th, table.horizontal thead, table.horizontal th { - border: 0; - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - table tbody, table.horizontal tbody { - border: 0; - display: table-row-group; } - table tr, table.horizontal tr { - display: block; - border: 0.0625rem solid var(--table-border-color); - border-radius: var(--universal-border-radius); - background: #fafafa; - padding: var(--universal-padding); - margin: var(--universal-margin); - margin-bottom: calc(2 * var(--universal-margin)); } - table th, table td, table.horizontal th, table.horizontal td { - width: auto; } - table td, table.horizontal td { - display: block; - border: 0; - text-align: right; } - table td:before, table.horizontal td:before { - content: attr(data-label); - float: left; - font-weight: 600; } - table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { - border-top: 0; } - table tbody tr:last-child td, table.horizontal tbody tr:last-child td { - border-right: 0; } } -:root { - --table-body-alt-back-color: #eee; } - -table tr:nth-of-type(2n) > td { - background: var(--table-body-alt-back-color); } - -@media screen and (max-width: 500px) { - table tr:nth-of-type(2n) { - background: var(--table-body-alt-back-color); } } -:root { - --table-body-hover-back-color: #90caf9; } - -table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { - background: var(--table-body-hover-back-color); } - -@media screen and (max-width: 500px) { - table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { - background: var(--table-body-hover-back-color); } } -/* - Definitions for contextual background elements, toasts and tooltips. -*/ -/* Contextual module CSS variable definitions */ -:root { - --mark-back-color: #0277bd; - --mark-fore-color: #fafafa; } - -mark { - background: var(--mark-back-color); - color: var(--mark-fore-color); - font-size: 0.95em; - line-height: 1em; - border-radius: var(--universal-border-radius); - padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } - mark.inline-block { - display: inline-block; - font-size: 1em; - line-height: 1.5; - padding: calc(var(--universal-padding) / 2) var(--universal-padding); } - -:root { - --toast-back-color: #424242; - --toast-fore-color: #fafafa; } - -.toast { - position: fixed; - bottom: calc(var(--universal-margin) * 3); - left: 50%; - transform: translate(-50%, -50%); - z-index: 1111; - color: var(--toast-fore-color); - background: var(--toast-back-color); - border-radius: calc(var(--universal-border-radius) * 16); - padding: var(--universal-padding) calc(var(--universal-padding) * 3); } - -:root { - --tooltip-back-color: #212121; - --tooltip-fore-color: #fafafa; } - -.tooltip { - position: relative; - display: inline-block; } - .tooltip:before, .tooltip:after { - position: absolute; - opacity: 0; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); - transition: all 0.3s; - z-index: 1010; - left: 50%; } - .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { - bottom: 75%; } - .tooltip.bottom:before, .tooltip.bottom:after { - top: 75%; } - .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { - opacity: 1; - clip: auto; - -webkit-clip-path: inset(0%); - clip-path: inset(0%); } - .tooltip:before { - content: ''; - background: transparent; - border: var(--universal-margin) solid transparent; - left: calc(50% - var(--universal-margin)); } - .tooltip:not(.bottom):before { - border-top-color: #212121; } - .tooltip.bottom:before { - border-bottom-color: #212121; } - .tooltip:after { - content: attr(aria-label); - color: var(--tooltip-fore-color); - background: var(--tooltip-back-color); - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - white-space: nowrap; - transform: translateX(-50%); } - .tooltip:not(.bottom):after { - margin-bottom: calc(2 * var(--universal-margin)); } - .tooltip.bottom:after { - margin-top: calc(2 * var(--universal-margin)); } - -:root { - --modal-overlay-color: rgba(0, 0, 0, 0.45); - --modal-close-color: #444; - --modal-close-hover-color: #f0f0f0; } - -[type="checkbox"].modal { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - [type="checkbox"].modal + div { - position: fixed; - top: 0; - left: 0; - display: none; - width: 100vw; - height: 100vh; - background: var(--modal-overlay-color); } - [type="checkbox"].modal + div .card { - margin: 0 auto; - max-height: 50vh; - overflow: auto; } - [type="checkbox"].modal + div .card .modal-close { - position: absolute; - top: 0; - right: 0; - width: 1.75rem; - height: 1.75rem; - border-radius: var(--universal-border-radius); - padding: var(--universal-padding); - margin: 0; - cursor: pointer; - transition: background 0.3s; } - [type="checkbox"].modal + div .card .modal-close:before { - display: block; - content: '\00D7'; - color: var(--modal-close-color); - position: relative; - font-family: sans-serif; - font-size: 1.75rem; - line-height: 1; - text-align: center; } - [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { - background: var(--modal-close-hover-color); } - [type="checkbox"].modal:checked + div { - display: flex; - flex: 0 1 auto; - z-index: 1200; } - [type="checkbox"].modal:checked + div .card .modal-close { - z-index: 1211; } - -:root { - --collapse-label-back-color: #e8e8e8; - --collapse-label-fore-color: #212121; - --collapse-label-hover-back-color: #f0f0f0; - --collapse-selected-label-back-color: #ececec; - --collapse-border-color: #ddd; - --collapse-content-back-color: #fafafa; - --collapse-selected-label-border-color: #0277bd; } - -.collapse { - width: calc(100% - 2 * var(--universal-margin)); - opacity: 1; - display: flex; - flex-direction: column; - margin: var(--universal-margin); - border-radius: var(--universal-border-radius); } - .collapse > [type="radio"], .collapse > [type="checkbox"] { - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); } - .collapse > label { - flex-grow: 1; - display: inline-block; - height: 1.5rem; - cursor: pointer; - transition: background 0.3s; - color: var(--collapse-label-fore-color); - background: var(--collapse-label-back-color); - border: 0.0625rem solid var(--collapse-border-color); - padding: calc(1.5 * var(--universal-padding)); } - .collapse > label:hover, .collapse > label:focus { - background: var(--collapse-label-hover-back-color); } - .collapse > label + div { - flex-basis: auto; - height: 1px; - width: 1px; - margin: -1px; - overflow: hidden; - position: absolute; - clip: rect(0 0 0 0); - -webkit-clip-path: inset(100%); - clip-path: inset(100%); - transition: max-height 0.3s; - max-height: 1px; } - .collapse > :checked + label { - background: var(--collapse-selected-label-back-color); - border-bottom-color: var(--collapse-selected-label-border-color); } - .collapse > :checked + label + div { - box-sizing: border-box; - position: relative; - width: 100%; - height: auto; - overflow: auto; - margin: 0; - background: var(--collapse-content-back-color); - border: 0.0625rem solid var(--collapse-border-color); - border-top: 0; - padding: var(--universal-padding); - clip: auto; - -webkit-clip-path: inset(0%); - clip-path: inset(0%); - max-height: 850px; } - .collapse > label:not(:first-of-type) { - border-top: 0; } - .collapse > label:first-of-type { - border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } - .collapse > label:last-of-type:not(:first-of-type) { - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - .collapse > label:last-of-type:first-of-type { - border-radius: var(--universal-border-radius); } - .collapse > :checked:last-of-type:not(:first-of-type) + label { - border-radius: 0; } - .collapse > :checked:last-of-type + label + div { - border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } - -/* - Custom elements for contextual background elements, toasts and tooltips. -*/ -mark.secondary { - --mark-back-color: #d32f2f; } - -mark.tertiary { - --mark-back-color: #308732; } - -mark.tag { - padding: calc(var(--universal-padding)/2) var(--universal-padding); - border-radius: 1em; } - -/* - Definitions for progress elements and spinners. -*/ -/* Progress module CSS variable definitions */ -:root { - --progress-back-color: #ddd; - --progress-fore-color: #555; } - -progress { - display: block; - vertical-align: baseline; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - height: 0.75rem; - width: calc(100% - 2 * var(--universal-margin)); - margin: var(--universal-margin); - border: 0; - border-radius: calc(2 * var(--universal-border-radius)); - background: var(--progress-back-color); - color: var(--progress-fore-color); } - progress::-webkit-progress-value { - background: var(--progress-fore-color); - border-top-left-radius: calc(2 * var(--universal-border-radius)); - border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } - progress::-webkit-progress-bar { - background: var(--progress-back-color); } - progress::-moz-progress-bar { - background: var(--progress-fore-color); - border-top-left-radius: calc(2 * var(--universal-border-radius)); - border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } - progress[value="1000"]::-webkit-progress-value { - border-radius: calc(2 * var(--universal-border-radius)); } - progress[value="1000"]::-moz-progress-bar { - border-radius: calc(2 * var(--universal-border-radius)); } - progress.inline { - display: inline-block; - vertical-align: middle; - width: 60%; } - -:root { - --spinner-back-color: #ddd; - --spinner-fore-color: #555; } - -@keyframes spinner-donut-anim { - 0% { - transform: rotate(0deg); } - 100% { - transform: rotate(360deg); } } -.spinner { - display: inline-block; - margin: var(--universal-margin); - border: 0.25rem solid var(--spinner-back-color); - border-left: 0.25rem solid var(--spinner-fore-color); - border-radius: 50%; - width: 1.25rem; - height: 1.25rem; - animation: spinner-donut-anim 1.2s linear infinite; } - -/* - Custom elements for progress bars and spinners. -*/ -progress.primary { - --progress-fore-color: #1976d2; } - -progress.secondary { - --progress-fore-color: #d32f2f; } - -progress.tertiary { - --progress-fore-color: #308732; } - -.spinner.primary { - --spinner-fore-color: #1976d2; } - -.spinner.secondary { - --spinner-fore-color: #d32f2f; } - -.spinner.tertiary { - --spinner-fore-color: #308732; } - -/* - Definitions for icons - powered by Feather (https://feathericons.com/). -*/ -span[class^='icon-'] { - display: inline-block; - height: 1em; - width: 1em; - vertical-align: -0.125em; - background-size: contain; - margin: 0 calc(var(--universal-margin) / 4); } - span[class^='icon-'].secondary { - -webkit-filter: invert(25%); - filter: invert(25%); } - span[class^='icon-'].inverse { - -webkit-filter: invert(100%); - filter: invert(100%); } - -span.icon-alert { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-bookmark { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-calendar { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-credit { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-edit { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } -span.icon-link { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-help { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-home { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } -span.icon-info { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-lock { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-mail { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } -span.icon-location { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } -span.icon-phone { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-rss { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } -span.icon-search { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-settings { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-share { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-cart { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } -span.icon-upload { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } -span.icon-user { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } - -/* - Definitions for utilities and helper classes. -*/ -/* Utility module CSS variable definitions */ -:root { - --generic-border-color: rgba(0, 0, 0, 0.3); - --generic-box-shadow: 0 0.25rem 0.25rem 0 rgba(0, 0, 0, 0.125), 0 0.125rem 0.125rem -0.125rem rgba(0, 0, 0, 0.25); } - -.hidden { - display: none !important; } - -.visually-hidden { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } - -.bordered { - border: 0.0625rem solid var(--generic-border-color) !important; } - -.rounded { - border-radius: var(--universal-border-radius) !important; } - -.circular { - border-radius: 50% !important; } - -.shadowed { - box-shadow: var(--generic-box-shadow) !important; } - -.responsive-margin { - margin: calc(var(--universal-margin) / 4) !important; } - @media screen and (min-width: 500px) { - .responsive-margin { - margin: calc(var(--universal-margin) / 2) !important; } } - @media screen and (min-width: 1280px) { - .responsive-margin { - margin: var(--universal-margin) !important; } } - -.responsive-padding { - padding: calc(var(--universal-padding) / 4) !important; } - @media screen and (min-width: 500px) { - .responsive-padding { - padding: calc(var(--universal-padding) / 2) !important; } } - @media screen and (min-width: 1280px) { - .responsive-padding { - padding: var(--universal-padding) !important; } } - -@media screen and (max-width: 499px) { - .hidden-sm { - display: none !important; } } -@media screen and (min-width: 500px) and (max-width: 1279px) { - .hidden-md { - display: none !important; } } -@media screen and (min-width: 1280px) { - .hidden-lg { - display: none !important; } } -@media screen and (max-width: 499px) { - .visually-hidden-sm { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } -@media screen and (min-width: 500px) and (max-width: 1279px) { - .visually-hidden-md { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } -@media screen and (min-width: 1280px) { - .visually-hidden-lg { - position: absolute !important; - width: 1px !important; - height: 1px !important; - margin: -1px !important; - border: 0 !important; - padding: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(100%) !important; - clip-path: inset(100%) !important; - overflow: hidden !important; } } - -/*# sourceMappingURL=mini-default.css.map */ diff --git a/Middlewares/Third_Party/SubGHz_Phy/_htmresc/st_logo.png b/Middlewares/Third_Party/SubGHz_Phy/_htmresc/st_logo.png deleted file mode 100644 index 8b80057f..00000000 Binary files a/Middlewares/Third_Party/SubGHz_Phy/_htmresc/st_logo.png and /dev/null differ diff --git a/Middlewares/Third_Party/SubGHz_Phy/radio.h b/Middlewares/Third_Party/SubGHz_Phy/radio.h index 04498af1..beb0ca3e 100644 --- a/Middlewares/Third_Party/SubGHz_Phy/radio.h +++ b/Middlewares/Third_Party/SubGHz_Phy/radio.h @@ -36,13 +36,13 @@ #define __RADIO_H__ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* Includes ------------------------------------------------------------------*/ #include #include -#include "radio_ex.h" /* Private typedef -----------------------------------------------------------*/ /*! @@ -52,9 +52,11 @@ typedef enum { MODEM_FSK = 0, MODEM_LORA, + /* ST_WORKAROUND_BEGIN: Upgraded modulations list */ MODEM_BPSK, MODEM_SIGFOX_TX, MODEM_SIGFOX_RX, + /* ST_WORKAROUND_END */ }RadioModems_t; /*! @@ -87,11 +89,11 @@ typedef struct * \param [IN] payload Received buffer pointer * \param [IN] size Received buffer size * \param [IN] rssi RSSI value computed while receiving the frame [dBm] - * \param [IN] snr SNR value computed while receiving the frame [dB] - * FSK : N/A ( set to 0 ) + * \param [IN] LoraSnr_FskCfo + * FSK : Carrier Frequency Offset in kHz * LoRa: SNR value in dB */ - void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); + void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t LoraSnr_FskCfo ); /*! * \brief Rx Timeout callback prototype. */ @@ -115,6 +117,8 @@ typedef struct void ( *CadDone ) ( bool channelActivityDetected ); }RadioEvents_t; +#include "radio_ex.h" /* ST_WORKAROUND: extended radio functions */ + /*! * \brief Radio driver definition */ @@ -331,6 +335,7 @@ struct Radio_s * \retval rssiValue Current RSSI value in [dBm] */ int16_t ( *Rssi )( RadioModems_t modem ); + /* ST_WORKAROUND_BEGIN: Force register addr to uint16_t */ /*! * \brief Writes the radio register at the specified address * @@ -361,6 +366,7 @@ struct Radio_s * \param [IN] size Number of registers to be read */ void ( *ReadRegisters )( uint16_t addr, uint8_t *buffer, uint8_t size ); + /* ST_WORKAROUND_END */ /*! * \brief Sets the maximum payload length. * @@ -404,6 +410,7 @@ struct Radio_s * \param [in] sleepTime Structure describing sleep timeout value */ void ( *SetRxDutyCycle ) ( uint32_t rxTime, uint32_t sleepTime ); + /* ST_WORKAROUND_BEGIN: extended radio functions */ /*! * @brief Sets the Transmitter in continuous PRBS mode * @@ -411,7 +418,7 @@ struct Radio_s */ void (*TxPrbs) ( void ); /*! - * @brief Sets the Transmitter in continuous unmodulated Carrier mode at power dBm + * @brief Sets the Transmitter in continuous un-modulated Carrier mode at power dBm */ void (*TxCw) ( int8_t power ); /*! @@ -438,10 +445,34 @@ struct Radio_s * lora field to be used if modem =GENERIC_LORA bpsk field to be used if modem =GENERIC_BPSK * \param [IN] power Sets the output power [dBm] - * \param [IN] timeout Transmission timeout [ms] + * \param [IN] timeout Reception timeout [ms] * \return 0 when no parameters error, -1 otherwise */ int32_t (*RadioSetTxGenericConfig)( GenericModems_t modem, TxConfigGeneric_t* config, int8_t power, uint32_t timeout ); + /*! + * \brief Starts sending long Packet, packet maybe short + * + * \param [IN] payload_size total payload size to be sent + \param [IN] timeout in ms + * \param [IN] TxLongPacketGetNextChunkCb callback to be implemented on user side to feed partial chunk + * buffer: source buffer allocated by the app + * size: size in bytes to feed + * \return 0 when no parameters error, -1 otherwise + */ + int32_t (*TransmitLongPacket)( uint16_t payload_size, uint32_t timeout,void (*TxLongPacketGetNextChunkCb) (uint8_t** buffer, uint8_t buffer_size) ); + + /*! + * \brief Starts receiving long Packet, packet maybe short + * + * \param [IN] boosted_mode boosted_mode: 0 normal Rx, 1:improved sensitivity + * \param [IN] timeout Reception timeout [ms] + * \param [IN] RxLongStorePacketChunkCb callback to be implemented on user side to record partial chunk in the application + * buffer: source buffer allocated in the radio driver + * size: size in bytes to record + * \return 0 when no parameters error, -1 otherwise + */ + int32_t (*ReceiveLongPacket)( uint8_t boosted_mode, uint32_t timeout, void (*RxLongStorePacketChunkCb) (uint8_t* buffer, uint8_t chunk_size) ); + /* ST_WORKAROUND_END */ }; /*! @@ -451,17 +482,9 @@ struct Radio_s * board implementation */ extern const struct Radio_s Radio; -/* Private defines -----------------------------------------------------------*/ -/* Private macros ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Global variables ----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Functions Definition ------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif // __RADIO_H__ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/SubGHz_Phy/radio_ex.h b/Middlewares/Third_Party/SubGHz_Phy/radio_ex.h index aa1e37eb..c836d54e 100644 --- a/Middlewares/Third_Party/SubGHz_Phy/radio_ex.h +++ b/Middlewares/Third_Party/SubGHz_Phy/radio_ex.h @@ -40,6 +40,10 @@ extern "C" { #endif /* Includes ------------------------------------------------------------------*/ + + + +/*******************************************Radio LORA enum*****************************************/ typedef enum { GENERIC_FSK = 0, @@ -47,7 +51,6 @@ typedef enum GENERIC_BPSK, }GenericModems_t; -/*******************************************Radio LORA enum*****************************************/ /*! * @brief Represents the possible spreading factor values in LoRa packet types */ @@ -124,10 +127,11 @@ typedef enum */ typedef enum { - RADIO_LORA_LOWDR_OPT_OFF = 0x00, /*Force to 0*/ - RADIO_LORA_LOWDR_OPT_ON = 0x01, /*Force to 1*/ - RADIO_LORA_LOWDR_OPT_AUTO = 0x02, /*Force to 1 when SF11 or SF12, 0 otherwise*/ + RADIO_LORA_LOWDR_OPT_OFF = 0x00, /*Forced to 0*/ + RADIO_LORA_LOWDR_OPT_ON = 0x01, /*Forced to 1*/ + RADIO_LORA_LOWDR_OPT_AUTO = 0x02, /*Forced to 1 when SF11 or SF12, 0 otherwise*/ }RADIO_Ld_Opt_t; + /*******************************************Radio FSK enum*****************************************/ /*! @@ -170,7 +174,8 @@ typedef enum typedef enum { RADIO_FSK_PACKET_FIXED_LENGTH = 0x00, //!< The packet is known on both sides, no header included in the packet - RADIO_FSK_PACKET_VARIABLE_LENGTH = 0x01, //!< The packet is on variable size, header included + RADIO_FSK_PACKET_VARIABLE_LENGTH = 0x01, //!< 1 byte packet length field inserted after the sync word*/ + RADIO_FSK_PACKET_2BYTES_LENGTH = 0x02 //!< 2 bytes packet length field inserted after the sync word, payload size greater than 255 bytes */ }RADIO_FSK_PacketLengthModes_t; /*! @@ -188,14 +193,18 @@ typedef enum }RADIO_FSK_CrcTypes_t; /*! - * @brief Radio whitening mode activated or deactivated + * @brief Radio whitening mode Off, CCIT or ibm */ typedef enum { - RADIO_FSK_DC_FREE_OFF = 0x00, - RADIO_FSK_DC_FREEWHITENING = 0x01, + RADIO_FSK_DC_FREE_OFF = 0x00, /*whitening Off*/ + RADIO_FSK_DC_FREEWHITENING = 0x01, /*whitening CCIT*/ + RADIO_FSK_DC_IBM_WHITENING = 0x02, /*whitening IBM*/ }RADIO_FSK_DcFree_t; +/*! + * @brief Radio Lora generic Rx parameters + */ typedef struct{ uint32_t StopTimerOnPreambleDetect; /*0 inactive, otherwise active*/ RADIO_LoRaSpreadingFactors_t SpreadingFactor; @@ -209,59 +218,79 @@ typedef struct{ RADIO_LoRaIQModes_t IqInverted; } generic_param_rx_lora_t; +/*! + * @brief Radio FSK generic Rx parameters + */ typedef struct{ uint32_t StopTimerOnPreambleDetect; RADIO_FSK_ModShapings_t ModulationShaping; uint32_t Bandwidth; - uint32_t BitRate; /*BitRate*/ - uint32_t PreambleLen; /*in Byte*/ + uint32_t BitRate; /* BitRate */ + uint32_t PreambleLen; /* Preamble length in Byte */ RADIO_FSK_PreambleDetection_t PreambleMinDetect; - uint8_t SyncWordLength; /*in Byte*/ - uint8_t* SyncWord; /*SyncWord Buffer*/ - uint32_t MaxPayloadLength; /*maximum Payload length to listen*/ - uint16_t whiteSeed; /*WhiteningSeed*/ + uint8_t SyncWordLength; /* SyncWord Buffer length in Byte*/ + uint8_t* SyncWord; /* SyncWord Buffer, 8 bytes max */ + uint32_t MaxPayloadLength; /* maximum Payload length to listen */ + uint16_t whiteSeed; /* WhiteningSeed, whitening can also be disabled by setting this field to 0 */ RADIO_FSK_AddressComp_t AddrComp; - RADIO_FSK_PacketLengthModes_t LengthMode; //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted - RADIO_FSK_CrcTypes_t CrcLength; //!< Size of the CRC block in the GFSK packet - uint16_t CrcPolynomial; + RADIO_FSK_PacketLengthModes_t LengthMode; /* If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted */ + RADIO_FSK_CrcTypes_t CrcLength; /* Size of the CRC block in the GFSK packet */ + uint16_t CrcPolynomial; /* Polynomial of the Crc*/ + uint16_t CrcSeed; /* Seed of the Crc*/ RADIO_FSK_DcFree_t Whitening; } generic_param_rx_fsk_t; +/*! + * @brief Radio generic Rx Configuration + */ typedef struct{ generic_param_rx_fsk_t fsk; generic_param_rx_lora_t lora; } RxConfigGeneric_t; +/*! + * @brief Radio BPSK generic Tx parameters + */ typedef struct{ - uint32_t BitRate; /*BitRate*/ + uint32_t BitRate; /*BitRate*/ } generic_param_tx_bpsk_t; +/*! + * @brief Radio Lora generic Tx parameters + */ typedef struct{ RADIO_LoRaSpreadingFactors_t SpreadingFactor; RADIO_LoRaBandwidths_t Bandwidth; RADIO_LoRaCodingRates_t Coderate; - RADIO_Ld_Opt_t LowDatarateOptimize;/*0 inactive, otherwise active*/ + RADIO_Ld_Opt_t LowDatarateOptimize; /*0 inactive, otherwise active*/ uint16_t PreambleLen; RADIO_LoRaPacketLengthsMode_t LengthMode; RADIO_LoRaCrcModes_t CrcMode; RADIO_LoRaIQModes_t IqInverted; } generic_param_tx_lora_t; +/*! + * @brief Radio FSK generic Tx parameters + */ typedef struct{ RADIO_FSK_ModShapings_t ModulationShaping; uint32_t Bandwidth; - uint32_t BitRate; /*BitRate*/ - uint32_t FrequencyDeviation; /*FrequencyDeviation*/ - uint32_t PreambleLen; /*in Byte*/ - uint8_t SyncWordLength; /*in Byte*/ - uint8_t* SyncWord; /*SyncWord Buffer*/ - uint16_t whiteSeed; /*WhiteningSeed*/ - RADIO_FSK_PacketLengthModes_t HeaderType; //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted - RADIO_FSK_CrcTypes_t CrcLength; //!< Size of the CRC block in the GFSK packet + uint32_t BitRate; /* BitRate */ + uint32_t FrequencyDeviation; /* FrequencyDeviation */ + uint32_t PreambleLen; /* in Byte */ + uint8_t SyncWordLength; /* in Byte */ + uint8_t* SyncWord; /* SyncWord Buffer, 8 bytes max */ + uint16_t whiteSeed; /* Whitening seed, whitening can be disabled by setting this field to 0 */ + RADIO_FSK_PacketLengthModes_t HeaderType; /* If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted */ + RADIO_FSK_CrcTypes_t CrcLength; /* Size of the CRC block in the GFSK packet */ uint16_t CrcPolynomial; + uint16_t CrcSeed; RADIO_FSK_DcFree_t Whitening; } generic_param_tx_fsk_t; +/*! + * @brief Radio generic Tx Configuration + */ typedef struct{ generic_param_tx_fsk_t fsk; generic_param_tx_lora_t lora; diff --git a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio.c b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio.c index f251a471..cd951ca7 100644 --- a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio.c +++ b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio.c @@ -27,18 +27,20 @@ * * @file radio.c * @author MCD Application Team - * @brief radio API definition + * @brief Radio driver API definition ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include #include "timer.h" #include "radio.h" +#include "radio_fw.h" #include "radio_driver.h" #include "radio_conf.h" #include "mw_log_conf.h" /* Private typedef -----------------------------------------------------------*/ +/* ST_WORKAROUND_BEGIN: Replace global variables by typedef struct */ /*! * Radio hardware and global parameters */ @@ -59,22 +61,14 @@ typedef struct SubgRf_s RadioIrqMasks_t RadioIrq; uint8_t AntSwitchPaSelect; } SubgRf_t; +/* ST_WORKAROUND_END */ -/*! - * FSK bandwidth definition - */ -typedef struct -{ - uint32_t bandwidth; - uint8_t RegValue; -} FskBandwidth_t; - -/* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ +/* ST_WORKAROUND_BEGIN: Add utilities macro to prevent missing header file */ #define RADIO_BIT_MASK(__n) (~(1<<__n)) /** - * \brief Calculates ceiling( X / N ) + * \brief Calculates ceiling division of ( X / N ) * * \param [IN] X numerator * \param [IN] N denominator @@ -83,15 +77,54 @@ typedef struct #ifndef DIVC #define DIVC( X, N ) ( ( ( X ) + ( N ) - 1 ) / ( N ) ) #endif -/* Private function prototypes -----------------------------------------------*/ -/*! - * \brief Returns the known FSK bandwidth registers value - * - * \param [IN] bandwidth Bandwidth value in Hz - * \retval regValue Bandwidth register value. - */ -static uint8_t RadioGetFskBandwidthRegValue( uint32_t bandwidth ); +/** + * \brief Calculates rounding division of ( X / N ) + * + * \param [IN] X numerator + * \param [IN] N denominator + * + */ +#ifndef DIVR +#define DIVR( X, N ) ( ( ( X ) + ( ((X)>0?(N):(N))>>1 ) ) / ( N ) ) +#endif +/* ST_WORKAROUND_END */ + +/* Private define ------------------------------------------------------------*/ +/* ST_WORKAROUND_BEGIN: Add radio defines to prevent missing header file */ +/*can be overridden in radio_conf.h*/ +#ifndef XTAL_FREQ +#define XTAL_FREQ 32000000UL +#endif +/*can be overridden in radio_conf.h*/ +#ifndef RADIO_IRQ_PROCESS_INIT +#define RADIO_IRQ_PROCESS_INIT() +#endif +/*can be overridden in radio_conf.h*/ +#ifndef RADIO_IRQ_PROCESS +#define RADIO_IRQ_PROCESS() RadioIrqProcess() +#endif +/*can be overridden in radio_conf.h*/ +#ifndef RADIO_RX_TIMEOUT_PROCESS +#define RADIO_RX_TIMEOUT_PROCESS() RadioOnRxTimeoutProcess() +#endif +/*can be overridden in radio_conf.h*/ +#ifndef RADIO_TX_TIMEOUT_PROCESS +#define RADIO_TX_TIMEOUT_PROCESS() RadioOnTxTimeoutProcess() +#endif + +#ifndef IRQ_TX_DBG +#define IRQ_TX_DBG ((uint16_t) 0) +#endif + +#ifndef IRQ_RX_DBG +#define IRQ_RX_DBG ((uint16_t) 0) +#endif + +#define RADIO_BUF_SIZE 255 +/* ST_WORKAROUND_END */ + +/* Private function prototypes -----------------------------------------------*/ /*! * \brief Initializes the radio * @@ -242,63 +275,6 @@ static void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, */ static bool RadioCheckRfFrequency( uint32_t frequency ); -/*! - * \brief Convert the bandwitdh enum to Hz value - * - * \param [IN] bw RF frequency to be checked - * \retval bandwidthInHz bandwidth value in Hertz - */ -static uint32_t RadioGetLoRaBandwidthInHz( RadioLoRaBandwidths_t bw ); - -/*! - * \brief Computes the time on air GSFK numerator - * - * \param [IN] datarate Sets the Datarate - * FSK : 600..300000 bits/s - * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, - * 10: 1024, 11: 2048, 12: 4096 chips] - * \param [IN] coderate Sets the coding rate (LoRa only) - * FSK : N/A ( set to 0 ) - * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] - * \param [IN] preambleLen Sets the Preamble length - * FSK : Number of bytes - * LoRa: Length in symbols (the hardware adds 4 more symbols) - * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] - * \param [IN] payloadLen Sets payload length when fixed length is used - * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] - * \retval numerator time on air GFSK numerator - */ -static uint32_t RadioGetGfskTimeOnAirNumerator( uint32_t datarate, uint8_t coderate, - uint16_t preambleLen, bool fixLen, uint8_t payloadLen, - bool crcOn ); - -/*! - * \brief Computes the time on air LoRa numerator - * - * \param [IN] bandwidth Sets the bandwidth - * FSK : >= 2600 and <= 250000 Hz - * LoRa: [0: 125 kHz, 1: 250 kHz, - * 2: 500 kHz, 3: Reserved] - * \param [IN] datarate Sets the Datarate - * FSK : 600..300000 bits/s - * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, - * 10: 1024, 11: 2048, 12: 4096 chips] - * \param [IN] coderate Sets the coding rate (LoRa only) - * FSK : N/A ( set to 0 ) - * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] - * \param [IN] preambleLen Sets the Preamble length - * FSK : Number of bytes - * LoRa: Length in symbols (the hardware adds 4 more symbols) - * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] - * \param [IN] payloadLen Sets payload length when fixed length is used - * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] - * \retval numerator time on air LoRa numerator - */ -static uint32_t RadioGetLoRaTimeOnAirNumerator( uint32_t bandwidth, - uint32_t datarate, uint8_t coderate, - uint16_t preambleLen, bool fixLen, uint8_t payloadLen, - bool crcOn ); - /*! * \brief Computes the packet time on air in ms for the given payload * @@ -377,6 +353,7 @@ static void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time */ static int16_t RadioRssi( RadioModems_t modem ); +/* ST_WORKAROUND_BEGIN: Force register addr to uint16_t */ /*! * \brief Writes the radio register at the specified address * @@ -410,6 +387,7 @@ static void RadioWriteRegisters( uint16_t addr, uint8_t *buffer, uint8_t size ); * \param [IN] size Number of registers to be read */ static void RadioReadRegisters( uint16_t addr, uint8_t *buffer, uint8_t size ); +/* ST_WORKAROUND_END */ /*! * \brief Sets the maximum payload length. @@ -470,6 +448,17 @@ static void RadioOnTxTimeoutIrq( void * context ); */ static void RadioOnRxTimeoutIrq( void * context ); +/*! + * \brief Rx timeout timer process + */ +static void RadioOnRxTimeoutProcess( void ); + +/*! + * \brief Tx timeout timer process + */ +static void RadioOnTxTimeoutProcess( void ); + +/* ST_WORKAROUND_BEGIN: extended radio functions */ /*! * @brief D-BPSK to BPSK * @@ -523,6 +512,64 @@ static int32_t RadioSetRxGenericConfig(GenericModems_t modem, RxConfigGeneric_t* static int32_t RadioSetTxGenericConfig(GenericModems_t modem, TxConfigGeneric_t *config, int8_t power, uint32_t timeout); +/*! + * \brief Convert the bandwidth enum to Hz value + * + * \param [IN] bw RF frequency to be checked + * \retval bandwidthInHz bandwidth value in Hertz + */ +static uint32_t RadioGetLoRaBandwidthInHz( RadioLoRaBandwidths_t bw ); + +/*! + * \brief Computes the time on air GFSK numerator + * + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] preambleLen Sets the Preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] payloadLen Sets payload length when fixed length is used + * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] + * \retval numerator time on air GFSK numerator + */ +static uint32_t RadioGetGfskTimeOnAirNumerator( uint32_t datarate, uint8_t coderate, + uint16_t preambleLen, bool fixLen, uint8_t payloadLen, + bool crcOn ); + +/*! + * \brief Computes the time on air LoRa numerator + * + * \param [IN] bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * \param [IN] datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * \param [IN] coderate Sets the coding rate (LoRa only) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * \param [IN] preambleLen Sets the Preamble length + * FSK : Number of bytes + * LoRa: Length in symbols (the hardware adds 4 more symbols) + * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] + * \param [IN] payloadLen Sets payload length when fixed length is used + * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] + * \retval numerator time on air LoRa numerator + */ +static uint32_t RadioGetLoRaTimeOnAirNumerator( uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint16_t preambleLen, bool fixLen, uint8_t payloadLen, + bool crcOn ); +/* ST_WORKAROUND_END */ + /* Private variables ---------------------------------------------------------*/ /*! * Radio driver structure initialization @@ -556,47 +603,21 @@ const struct Radio_s Radio = RadioIrqProcess, RadioRxBoosted, RadioSetRxDutyCycle, + /* ST_WORKAROUND_BEGIN: extended radio functions */ RadioTxPrbs, RadioTxCw, RadioSetRxGenericConfig, RadioSetTxGenericConfig, -}; - - -/*! - * Precomputed FSK bandwidth registers values - */ -const FskBandwidth_t FskBandwidths[] = -{ - { 4800 , 0x1F }, - { 5800 , 0x17 }, - { 7300 , 0x0F }, - { 9700 , 0x1E }, - { 11700 , 0x16 }, - { 14600 , 0x0E }, - { 19500 , 0x1D }, - { 23400 , 0x15 }, - { 29300 , 0x0D }, - { 39000 , 0x1C }, - { 46900 , 0x14 }, - { 58600 , 0x0C }, - { 78200 , 0x1B }, - { 93800 , 0x13 }, - { 117300, 0x0B }, - { 156200, 0x1A }, - { 187200, 0x12 }, - { 234300, 0x0A }, - { 312000, 0x19 }, - { 373600, 0x11 }, - { 467000, 0x09 }, - { 500000, 0x00 }, // Invalid Bandwidth + RFW_TransmitLongPacket, + RFW_ReceiveLongPacket + /* ST_WORKAROUND_END */ }; const RadioLoRaBandwidths_t Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 }; -static uint8_t MaxPayloadLength = RADIO_RX_BUF_SIZE; +static uint8_t MaxPayloadLength = RADIO_BUF_SIZE; -static uint8_t RadioRxPayload[RADIO_RX_BUF_SIZE]; +static uint8_t RadioBuffer[RADIO_BUF_SIZE]; /* * Radio callbacks variable @@ -613,379 +634,115 @@ SubgRf_t SubgRf; */ TimerEvent_t TxTimeoutTimer; TimerEvent_t RxTimeoutTimer; -/* Exported functions ---------------------------------------------------------*/ -static int32_t RadioSetRxGenericConfig( GenericModems_t modem, RxConfigGeneric_t* config, uint32_t rxContinuous, uint32_t symbTimeout) + +/* Private functions ---------------------------------------------------------*/ + +static void RadioInit( RadioEvents_t *events ) { - int32_t status=0; - uint8_t syncword[8]={0}; - uint8_t MaxPayloadLength; - if( rxContinuous != 0 ) + RadioEvents = events; + + SubgRf.RxContinuous = false; + SubgRf.TxTimeout = 0; + SubgRf.RxTimeout = 0; + + SUBGRF_Init( RadioOnDioIrq ); + /*SubgRf.publicNetwork set to false*/ + RadioSetPublicNetwork( false ); + + RADIO_IRQ_PROCESS_INIT(); + + SUBGRF_SetRegulatorMode( ); + + SUBGRF_SetBufferBaseAddress( 0x00, 0x00 ); + SUBGRF_SetTxParams(RFO_LP, 0, RADIO_RAMP_200_US); + SUBGRF_SetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + + /* ST_WORKAROUND_BEGIN: Sleep radio */ + RadioSleep(); + /* ST_WORKAROUND_END */ + // Initialize driver timeout timers + TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq ); + TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq ); + TimerStop( &TxTimeoutTimer ); + TimerStop( &RxTimeoutTimer ); +} + +static RadioState_t RadioGetStatus( void ) +{ + switch( SUBGRF_GetOperatingMode( ) ) { - symbTimeout = 0; + case MODE_TX: + return RF_TX_RUNNING; + case MODE_RX: + return RF_RX_RUNNING; + case MODE_CAD: + return RF_CAD; + default: + return RF_IDLE; } - SubgRf.RxContinuous = (rxContinuous==0)? false :true; +} +static void RadioSetModem( RadioModems_t modem ) +{ + SubgRf.Modem = modem; + RFW_SetRadioModem(modem); switch( modem ) { - case GENERIC_FSK: - if ((config->fsk.BitRate== 0) || (config->fsk.PreambleLen== 0)) - { - return -1; - } - if ( config->fsk.SyncWordLength>8) - { - return -1; - } - else - { - for(int i =0; ifsk.SyncWordLength; i++) - { - syncword[i]=config->fsk.SyncWord[i]; - } - } - if( config->fsk.LengthMode == RADIO_FSK_PACKET_FIXED_LENGTH ) - { - MaxPayloadLength = config->fsk.MaxPayloadLength; - } - else - { - MaxPayloadLength = 0xFF; - } + default: + case MODEM_FSK: + SUBGRF_SetPacketType( PACKET_TYPE_GFSK ); + // When switching to GFSK mode the LoRa SyncWord register value is reset + // Thus, we also reset the RadioPublicNetwork variable + SubgRf.PublicNetwork.Current = false; + break; + case MODEM_LORA: + SUBGRF_SetPacketType( PACKET_TYPE_LORA ); + // Public/Private network register is reset when switching modems + if( SubgRf.PublicNetwork.Current != SubgRf.PublicNetwork.Previous ) + { + SubgRf.PublicNetwork.Current = SubgRf.PublicNetwork.Previous; + RadioSetPublicNetwork( SubgRf.PublicNetwork.Current ); + } + break; + case MODEM_BPSK: + SUBGRF_SetPacketType( PACKET_TYPE_BPSK ); + // When switching to BPSK mode the LoRa SyncWord register value is reset + // Thus, we also reset the RadioPublicNetwork variable + SubgRf.PublicNetwork.Current = false; + break; + case MODEM_SIGFOX_TX: + SUBGRF_SetPacketType( PACKET_TYPE_BPSK ); + // When switching to BPSK mode the LoRa SyncWord register value is reset + // Thus, we also reset the RadioPublicNetwork variable + SubgRf.PublicNetwork.Current = false; + break; + case MODEM_SIGFOX_RX: + SUBGRF_SetPacketType( PACKET_TYPE_GFSK ); + // When switching to GFSK mode the LoRa SyncWord register value is reset + // Thus, we also reset the RadioPublicNetwork variable + SubgRf.PublicNetwork.Current = false; + break; + } +} - SUBGRF_SetStopRxTimerOnPreambleDetect( (config->fsk.StopTimerOnPreambleDetect==0)? false:true ); +static void RadioSetChannel( uint32_t freq ) +{ + SUBGRF_SetRfFrequency( freq ); +} - SubgRf.ModulationParams.PacketType = PACKET_TYPE_GFSK; - SubgRf.ModulationParams.Params.Gfsk.BitRate = config->fsk.BitRate; - SubgRf.ModulationParams.Params.Gfsk.ModulationShaping = (RadioModShapings_t) config->fsk.ModulationShaping; - SubgRf.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue(config->fsk.Bandwidth); +static bool RadioIsChannelFree( uint32_t freq, uint32_t rxBandwidth, int16_t rssiThresh, uint32_t maxCarrierSenseTime ) +{ + bool status = true; + int16_t rssi = 0; + uint32_t carrierSenseTime = 0; - SubgRf.PacketParams.PacketType = PACKET_TYPE_GFSK; - SubgRf.PacketParams.Params.Gfsk.PreambleLength = ( config->fsk.PreambleLen) << 3 ; // convert byte into bit - SubgRf.PacketParams.Params.Gfsk.PreambleMinDetect = (RadioPreambleDetection_t) config->fsk.PreambleMinDetect; - SubgRf.PacketParams.Params.Gfsk.SyncWordLength = (config->fsk.SyncWordLength) << 3; // convert byte into bit - SubgRf.PacketParams.Params.Gfsk.AddrComp = (RadioAddressComp_t)config->fsk.AddrComp; - SubgRf.PacketParams.Params.Gfsk.HeaderType = (RadioPacketLengthModes_t) config->fsk.LengthMode; - SubgRf.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength; - SubgRf.PacketParams.Params.Gfsk.CrcLength = (RadioCrcTypes_t) config->fsk.CrcLength; - SubgRf.PacketParams.Params.Gfsk.DcFree = (RadioDcFree_t) config->fsk.Whitening; + /* ST_WORKAROUND_BEGIN: Prevent multiple sleeps with TXCO delay */ + RadioStandby( ); + /* ST_WORKAROUND_END */ - RadioStandby( ); - RadioSetModem( MODEM_FSK ); - SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); - SUBGRF_SetPacketParams( &SubgRf.PacketParams ); - SUBGRF_SetSyncWord( syncword ); - SUBGRF_SetWhiteningSeed( config->fsk.whiteSeed ); - SUBGRF_SetCrcPolynomial(config->fsk.CrcPolynomial ); - /*timeout*/ + RadioSetModem( MODEM_FSK ); - SubgRf.RxTimeout = ( uint32_t )( (symbTimeout * 1000* 8 )/config->fsk.BitRate ); - break; - case GENERIC_LORA: - if (config->lora.PreambleLen== 0) - { - return -1; - } - - if( config->lora.LengthMode == RADIO_LORA_PACKET_FIXED_LENGTH ) - { - MaxPayloadLength = config->fsk.MaxPayloadLength; - } - else - { - MaxPayloadLength = 0xFF; - } - SUBGRF_SetStopRxTimerOnPreambleDetect( (config->lora.StopTimerOnPreambleDetect==0)? false:true ); - SUBGRF_SetLoRaSymbNumTimeout( symbTimeout ); - - SubgRf.ModulationParams.PacketType = PACKET_TYPE_LORA; - SubgRf.ModulationParams.Params.LoRa.SpreadingFactor = (RadioLoRaSpreadingFactors_t) config->lora.SpreadingFactor; - SubgRf.ModulationParams.Params.LoRa.Bandwidth = (RadioLoRaBandwidths_t) config->lora.Bandwidth; - SubgRf.ModulationParams.Params.LoRa.CodingRate = (RadioLoRaCodingRates_t) config->lora.Coderate; - switch (config->lora.LowDatarateOptimize) - { - case RADIO_LORA_LOWDR_OPT_OFF: - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; - break; - case RADIO_LORA_LOWDR_OPT_ON: - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; - break; - case RADIO_LORA_LOWDR_OPT_AUTO: - if ((config->lora.SpreadingFactor==RADIO_LORA_SF11) || (config->lora.SpreadingFactor==RADIO_LORA_SF12)) - { - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; - } - else - { - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; - } - break; - default: - break; - } - - SubgRf.PacketParams.PacketType = PACKET_TYPE_LORA; - SubgRf.PacketParams.Params.LoRa.PreambleLength = config->lora.PreambleLen; - SubgRf.PacketParams.Params.LoRa.HeaderType = (RadioLoRaPacketLengthsMode_t) config->lora.LengthMode; - SubgRf.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; - SubgRf.PacketParams.Params.LoRa.CrcMode = (RadioLoRaCrcModes_t) config->lora.CrcMode; - SubgRf.PacketParams.Params.LoRa.InvertIQ = (RadioLoRaIQModes_t) config->lora.IqInverted; - - RadioStandby( ); - RadioSetModem( MODEM_LORA ); - SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); - SUBGRF_SetPacketParams( &SubgRf.PacketParams ); - - // WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4 - if( SubgRf.PacketParams.Params.LoRa.InvertIQ == LORA_IQ_INVERTED ) - { - // RegIqPolaritySetup = @address 0x0736 - SUBGRF_WriteRegister( 0x0736, SUBGRF_ReadRegister( 0x0736 ) & ~( 1 << 2 ) ); - } - else - { - // RegIqPolaritySetup @address 0x0736 - SUBGRF_WriteRegister( 0x0736, SUBGRF_ReadRegister( 0x0736 ) | ( 1 << 2 ) ); - } - // WORKAROUND END - - // Timeout Max, Timeout handled directly in SetRx function - SubgRf.RxTimeout = 0xFFFF; - break; - default: - break; - } - return status; -} - -static int32_t RadioSetTxGenericConfig( GenericModems_t modem, TxConfigGeneric_t* config, int8_t power, uint32_t timeout ) -{ - uint8_t syncword[8]={0}; - switch( modem ) - { - case GENERIC_FSK: - if ((config->fsk.BitRate== 0) || (config->fsk.PreambleLen== 0)) - { - return -1; - } - if ( config->fsk.SyncWordLength>8) - { - return -1; - } - else - { - for(int i =0; ifsk.SyncWordLength; i++) - { - syncword[i]=config->fsk.SyncWord[i]; - } - } - SubgRf.ModulationParams.PacketType = PACKET_TYPE_GFSK; - SubgRf.ModulationParams.Params.Gfsk.BitRate = config->fsk.BitRate; - SubgRf.ModulationParams.Params.Gfsk.ModulationShaping = (RadioModShapings_t) config->fsk.ModulationShaping; - SubgRf.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( config->fsk.Bandwidth ); - SubgRf.ModulationParams.Params.Gfsk.Fdev = config->fsk.FrequencyDeviation; - - SubgRf.PacketParams.PacketType = PACKET_TYPE_GFSK; - SubgRf.PacketParams.Params.Gfsk.PreambleLength = ( config->fsk.PreambleLen << 3 ); // convert byte into bit - SubgRf.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; //don't care in tx - SubgRf.PacketParams.Params.Gfsk.SyncWordLength = (config->fsk.SyncWordLength ) << 3 ; // convert byte into bit - SubgRf.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; /*don't care in tx*/ - SubgRf.PacketParams.Params.Gfsk.HeaderType = (RadioPacketLengthModes_t) config->fsk.HeaderType; - SubgRf.PacketParams.Params.Gfsk.CrcLength = (RadioCrcTypes_t) config->fsk.CrcLength; - SubgRf.PacketParams.Params.Gfsk.DcFree = (RadioDcFree_t) config->fsk.Whitening; - - RadioStandby( ); - RadioSetModem( MODEM_FSK ); - SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); - SUBGRF_SetPacketParams( &SubgRf.PacketParams ); - SUBGRF_SetSyncWord( syncword ); - SUBGRF_SetWhiteningSeed( config->fsk.whiteSeed ); - SUBGRF_SetCrcPolynomial(config->fsk.CrcPolynomial ); - break; - case GENERIC_LORA: - SubgRf.ModulationParams.PacketType = PACKET_TYPE_LORA; - SubgRf.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) config->lora.SpreadingFactor; - SubgRf.ModulationParams.Params.LoRa.Bandwidth = (RadioLoRaBandwidths_t) config->lora.Bandwidth; - SubgRf.ModulationParams.Params.LoRa.CodingRate = (RadioLoRaCodingRates_t) config->lora.Coderate; - switch (config->lora.LowDatarateOptimize) - { - case RADIO_LORA_LOWDR_OPT_OFF: - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; - break; - case RADIO_LORA_LOWDR_OPT_ON: - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; - break; - case RADIO_LORA_LOWDR_OPT_AUTO: - if ((config->lora.SpreadingFactor==RADIO_LORA_SF11) || (config->lora.SpreadingFactor==RADIO_LORA_SF12)) - { - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; - } - else - { - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; - } - break; - default: - break; - } - SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = (config->lora.LowDatarateOptimize==0)?0:1; - - SubgRf.PacketParams.PacketType = PACKET_TYPE_LORA; - SubgRf.PacketParams.Params.LoRa.PreambleLength = config->lora.PreambleLen; - SubgRf.PacketParams.Params.LoRa.HeaderType = (RadioLoRaPacketLengthsMode_t) config->lora.LengthMode; - SubgRf.PacketParams.Params.LoRa.CrcMode = (RadioLoRaCrcModes_t) config->lora.CrcMode; - SubgRf.PacketParams.Params.LoRa.InvertIQ = (RadioLoRaIQModes_t) config->lora.IqInverted; - - RadioStandby( ); - RadioSetModem( MODEM_LORA ); - SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); - SUBGRF_SetPacketParams( &SubgRf.PacketParams ); - // WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1 - if( SubgRf.ModulationParams.Params.LoRa.Bandwidth == LORA_BW_500 ) - { - // RegTxModulation = @address 0x0889 - SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) & ~( 1 << 2 ) ); - } - else - { - // RegTxModulation = @address 0x0889 - SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) | ( 1 << 2 ) ); - } - // WORKAROUND END - break; - case GENERIC_BPSK: - if ((config->fsk.BitRate== 0) || (config->fsk.BitRate> 1000)) - { - return -1; - } - RadioSetModem( MODEM_BPSK ); - SubgRf.ModulationParams.PacketType = PACKET_TYPE_BPSK; - SubgRf.ModulationParams.Params.Bpsk.BitRate = config->bpsk.BitRate; - SubgRf.ModulationParams.Params.Bpsk.ModulationShaping = MOD_SHAPING_DBPSK; - SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); - break; - default: - break; - } - - SubgRf.AntSwitchPaSelect = SUBGRF_SetRfTxPower( power ); - SubgRf.TxTimeout = timeout; - return 0; -} - -/* Private functions ---------------------------------------------------------*/ -static uint8_t RadioGetFskBandwidthRegValue( uint32_t bandwidth ) -{ - uint8_t i; - - if( bandwidth == 0 ) - { - return( 0x1F ); - } - - /* ST_WORKAROUND_BEGIN: Simplified loop */ - for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ); i++ ) - { - if ( bandwidth < FskBandwidths[i].bandwidth ) - { - return FskBandwidths[i].RegValue; - } - } - /* ST_WORKAROUND_END */ - // ERROR: Value not found - while( 1 ); -} - -static void RadioInit( RadioEvents_t *events ) -{ - RadioEvents = events; - - SubgRf.RxContinuous = false; - SubgRf.TxTimeout = 0; - SubgRf.RxTimeout = 0; - - SUBGRF_Init( RadioOnDioIrq ); - /*SubgRf.publicNetwork set to false*/ - RadioSetPublicNetwork( false ); - - SUBGRF_SetRegulatorMode( ); - - SUBGRF_SetBufferBaseAddress( 0x00, 0x00 ); - SUBGRF_SetTxParams(RFO_LP, 0, RADIO_RAMP_200_US); - SUBGRF_SetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); - - /* ST_WORKAROUND_BEGIN: Sleep radio */ - RadioSleep(); - /* ST_WORKAROUND_END */ - // Initialize driver timeout timers - TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq ); - TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq ); - TimerStop( &TxTimeoutTimer ); - TimerStop( &RxTimeoutTimer ); -} - -static RadioState_t RadioGetStatus( void ) -{ - switch( SUBGRF_GetOperatingMode( ) ) - { - case MODE_TX: - return RF_TX_RUNNING; - case MODE_RX: - return RF_RX_RUNNING; - case MODE_CAD: - return RF_CAD; - default: - return RF_IDLE; - } -} - -static void RadioSetModem( RadioModems_t modem ) -{ - SubgRf.Modem = modem; - switch( modem ) - { - default: - case MODEM_FSK: - SUBGRF_SetPacketType( PACKET_TYPE_GFSK ); - // When switching to GFSK mode the LoRa SyncWord register value is reset - // Thus, we also reset the RadioPublicNetwork variable - SubgRf.PublicNetwork.Current = false; - break; - case MODEM_LORA: - SUBGRF_SetPacketType( PACKET_TYPE_LORA ); - // Public/Private network register is reset when switching modems - if( SubgRf.PublicNetwork.Current != SubgRf.PublicNetwork.Previous ) - { - SubgRf.PublicNetwork.Current = SubgRf.PublicNetwork.Previous; - RadioSetPublicNetwork( SubgRf.PublicNetwork.Current ); - } - break; - case MODEM_SIGFOX_TX: - SUBGRF_SetPacketType( PACKET_TYPE_BPSK ); - break; - case MODEM_SIGFOX_RX: - SUBGRF_SetPacketType( PACKET_TYPE_GFSK ); - break; - } -} - -static void RadioSetChannel( uint32_t freq ) -{ - SUBGRF_SetRfFrequency( freq ); -} - -static bool RadioIsChannelFree( uint32_t freq, uint32_t rxBandwidth, int16_t rssiThresh, uint32_t maxCarrierSenseTime ) -{ - bool status = true; - int16_t rssi = 0; - uint32_t carrierSenseTime = 0; - - /* ST_WORKAROUND_BEGIN: Prevent multiple sleeps with TXCO delay */ - RadioStandby( ); - /* ST_WORKAROUND_END */ - - RadioSetModem( MODEM_FSK ); - - RadioSetChannel( freq ); + RadioSetChannel( freq ); // Set Rx bandwidth. Other parameters are not used. RadioSetRxConfig( MODEM_FSK, rxBandwidth, 600, 0, rxBandwidth, 3, 0, false, @@ -1020,10 +777,10 @@ static uint32_t RadioRandom( void ) /* * Radio setup for random number generation */ - /* Set LoRa modem ON */ + // Set LoRa modem ON RadioSetModem( MODEM_LORA ); - /* Disable LoRa modem interrupts */ + // Disable LoRa modem interrupts SUBGRF_SetDioIrqParams( IRQ_RADIO_NONE, IRQ_RADIO_NONE, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); rnd = SUBGRF_GetRandom(); @@ -1042,6 +799,7 @@ static void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, uint8_t modReg; SubgRf.RxContinuous = rxContinuous; + RFW_DeInit(); /* ST_WORKAROUND: Switch Off FwPacketDecoding by default */ if( rxContinuous == true ) { symbTimeout = 0; @@ -1064,7 +822,7 @@ static void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, SubgRf.ModulationParams.Params.Gfsk.BitRate = datarate; SubgRf.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_05; SubgRf.ModulationParams.Params.Gfsk.Fdev = 800; - SubgRf.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + SubgRf.ModulationParams.Params.Gfsk.Bandwidth = SUBGRF_GetFskBandwidthRegValue( bandwidth ); SubgRf.PacketParams.PacketType = PACKET_TYPE_GFSK; SubgRf.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit @@ -1095,7 +853,7 @@ static void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, modReg&=( RADIO_BIT_MASK(2) & RADIO_BIT_MASK(3) & RADIO_BIT_MASK(4) ); RadioWrite(0x89b, (modReg| (0x1<<3) ) ); - /* Biger afc_pbl_len (better frequency correction). Reg 0x6d1, bits[3 :4] = 0x3 */ + /* Bigger afc_pbl_len (better frequency correction). Reg 0x6d1, bits[3 :4] = 0x3 */ modReg= RadioRead(0x6d1); modReg&=( RADIO_BIT_MASK(3) & RADIO_BIT_MASK(4) ); RadioWrite(0x6d1, (modReg| (0x3<<3) )); @@ -1104,7 +862,7 @@ static void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, modReg= RadioRead(0x6ac); modReg&=( RADIO_BIT_MASK(4) & RADIO_BIT_MASK(5) & RADIO_BIT_MASK(6) ); RadioWrite(0x6ac, (modReg| (0x5<<4) )); - + /*timeout unused when SubgRf.RxContinuous*/ SubgRf.RxTimeout = ( uint32_t )(( symbTimeout * 8 * 1000 ) /datarate); break; case MODEM_FSK: @@ -1113,7 +871,7 @@ static void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, SubgRf.ModulationParams.Params.Gfsk.BitRate = datarate; SubgRf.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; - SubgRf.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + SubgRf.ModulationParams.Params.Gfsk.Bandwidth = SUBGRF_GetFskBandwidthRegValue( bandwidth ); SubgRf.PacketParams.PacketType = PACKET_TYPE_GFSK; SubgRf.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit @@ -1139,6 +897,7 @@ static void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, SUBGRF_SetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); SUBGRF_SetWhiteningSeed( 0x01FF ); + /*timeout unused when SubgRf.RxContinuous*/ SubgRf.RxTimeout = ( uint32_t )(( symbTimeout * 8 * 1000 ) /datarate); break; @@ -1190,20 +949,20 @@ static void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, SUBGRF_SetPacketParams( &SubgRf.PacketParams ); SUBGRF_SetLoRaSymbNumTimeout( symbTimeout ); - /* WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4 */ + // WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4 if( SubgRf.PacketParams.Params.LoRa.InvertIQ == LORA_IQ_INVERTED ) { - /* RegIqPolaritySetup = @address 0x0736 */ + // RegIqPolaritySetup = @address 0x0736 SUBGRF_WriteRegister( 0x0736, SUBGRF_ReadRegister( 0x0736 ) & ~( 1 << 2 ) ); } else { - /* RegIqPolaritySetup @address 0x0736 */ + // RegIqPolaritySetup @address 0x0736 SUBGRF_WriteRegister( 0x0736, SUBGRF_ReadRegister( 0x0736 ) | ( 1 << 2 ) ); } - /* WORKAROUND END */ + // WORKAROUND END - /* Timeout Max, Timeout handled directly in SetRx function */ + // Timeout Max, Timeout handled directly in SetRx function SubgRf.RxTimeout = 0xFFFF; break; @@ -1218,23 +977,15 @@ static void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, bool fixLen, bool crcOn, bool freqHopOn, uint8_t hopPeriod, bool iqInverted, uint32_t timeout ) { - + RFW_DeInit(); /* ST_WORKAROUND: Switch Off FwPacketDecoding by default */ switch( modem ) { - case MODEM_SIGFOX_TX: - RadioSetModem(MODEM_SIGFOX_TX); - SubgRf.ModulationParams.PacketType = PACKET_TYPE_BPSK; - SubgRf.ModulationParams.Params.Bpsk.BitRate = datarate; - SubgRf.ModulationParams.Params.Bpsk.ModulationShaping = MOD_SHAPING_DBPSK; - SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); - break; - case MODEM_FSK: SubgRf.ModulationParams.PacketType = PACKET_TYPE_GFSK; SubgRf.ModulationParams.Params.Gfsk.BitRate = datarate; SubgRf.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; - SubgRf.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); + SubgRf.ModulationParams.Params.Gfsk.Bandwidth = SUBGRF_GetFskBandwidthRegValue( bandwidth ); SubgRf.ModulationParams.Params.Gfsk.Fdev = fdev; SubgRf.PacketParams.PacketType = PACKET_TYPE_GFSK; @@ -1296,7 +1047,6 @@ static void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, { SubgRf.PacketParams.Params.LoRa.PreambleLength = preambleLen; } - SubgRf.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; SubgRf.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; SubgRf.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; @@ -1306,24 +1056,24 @@ static void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, RadioSetModem( ( SubgRf.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); SUBGRF_SetPacketParams( &SubgRf.PacketParams ); + break; + + case MODEM_SIGFOX_TX: + RadioSetModem(MODEM_SIGFOX_TX); + SubgRf.ModulationParams.PacketType = PACKET_TYPE_BPSK; + SubgRf.ModulationParams.Params.Bpsk.BitRate = datarate; + SubgRf.ModulationParams.Params.Bpsk.ModulationShaping = MOD_SHAPING_DBPSK; + SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); + break; + default: break; } - /* WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1 */ - if( ( modem == MODEM_LORA ) && ( SubgRf.ModulationParams.Params.LoRa.Bandwidth == LORA_BW_500 ) ) - { - /* RegTxModulation = @address 0x0889 */ - SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) & ~( 1 << 2 ) ); - } - else - { - /* RegTxModulation = @address 0x0889 */ - SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) | ( 1 << 2 ) ); - } - /* WORKAROUND END */ + SubgRf.AntSwitchPaSelect = SUBGRF_SetRfTxPower( power ); + RFW_SetAntSwitch( SubgRf.AntSwitchPaSelect ); /* ST_WORKAROUND: ?????? */ SubgRf.TxTimeout = timeout; } @@ -1377,19 +1127,6 @@ static uint32_t RadioGetGfskTimeOnAirNumerator( uint32_t datarate, uint8_t coder uint16_t preambleLen, bool fixLen, uint8_t payloadLen, bool crcOn ) { - /* - const RadioAddressComp_t addrComp = RADIO_ADDRESSCOMP_FILT_OFF; - const uint8_t syncWordLength = 3; - - return ( preambleLen << 3 ) + - ( ( fixLen == false ) ? 8 : 0 ) + - ( syncWordLength << 3 ) + - ( ( payloadLen + - ( addrComp == RADIO_ADDRESSCOMP_FILT_OFF ? 0 : 1 ) + - ( ( crcOn == true ) ? 2 : 0 ) - ) << 3 - ); - */ /* ST_WORKAROUND_BEGIN: Simplified calculation without const values */ return ( preambleLen << 3 ) + ( ( fixLen == false ) ? 8 : 0 ) + 24 + @@ -1405,7 +1142,7 @@ static uint32_t RadioGetLoRaTimeOnAirNumerator( uint32_t bandwidth, int32_t crDenom = coderate + 4; bool lowDatareOptimize = false; - /* Ensure that the preamble length is at least 12 symbols when using SF5 or SF6 */ + // Ensure that the preamble length is at least 12 symbols when using SF5 or SF6 if( ( datarate == 5 ) || ( datarate == 6 ) ) { if( preambleLen < 12 ) @@ -1491,16 +1228,17 @@ static uint32_t RadioTimeOnAir( RadioModems_t modem, uint32_t bandwidth, break; } // Perform integral ceil() - return DIVC(numerator, denominator); + return DIVC(numerator, denominator); /* ST_WORKAROUND : simplified calculation with macro usage */ } static void RadioSend( uint8_t *buffer, uint8_t size ) { - /* Radio IRQ is set to DIO1 by default */ - SUBGRF_SetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, - IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + /* ST_WORKAROUND_BEGIN : Set the debug pin and update the radio switch */ + SUBGRF_SetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_TX_DBG, + IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_TX_DBG, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + /* ST_WORKAROUND_END */ /* ST_WORKAROUND_BEGIN : Set the debug pin and update the radio switch */ /* Set DBG pin */ @@ -1508,8 +1246,17 @@ static void RadioSend( uint8_t *buffer, uint8_t size ) /* Set RF switch */ SUBGRF_SetSwitch(SubgRf.AntSwitchPaSelect, RFSWITCH_TX); - /* ST_WORKAROUND_END */ - + /* WORKAROUND - Modulation Quality with 500 kHz LoRaTM Bandwidth*/ + /* RegTxModulation = @address 0x0889 */ + if((SubgRf.Modem==MODEM_LORA) && (SubgRf.ModulationParams.Params.LoRa.Bandwidth == LORA_BW_500 )) + { + SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) & ~( 1 << 2 ) ); + } + else + { + SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) | ( 1 << 2 ) ); + } + /* WORKAROUND END */ switch(SubgRf.Modem) { case MODEM_LORA: @@ -1521,9 +1268,27 @@ static void RadioSend( uint8_t *buffer, uint8_t size ) } case MODEM_FSK: { - SubgRf.PacketParams.Params.Gfsk.PayloadLength = size; - SUBGRF_SetPacketParams( &SubgRf.PacketParams ); - SUBGRF_SendPayload( buffer, size, 0 ); + if ( 1UL == RFW_Is_Init( ) ) + { + uint8_t outsize; + if ( 0UL == RFW_TransmitInit( buffer,size, &outsize ) ) + { + SubgRf.PacketParams.Params.Gfsk.PayloadLength = outsize; + SUBGRF_SetPacketParams( &SubgRf.PacketParams ); + SUBGRF_SendPayload( buffer, outsize, 0 ); + } + else + { + MW_LOG( TS_ON, VLEVEL_M, "RadioSend Oversize\r\n"); + return; + } + } + else + { + SubgRf.PacketParams.Params.Gfsk.PayloadLength = size; + SUBGRF_SetPacketParams( &SubgRf.PacketParams ); + SUBGRF_SendPayload( buffer, size, 0 ); + } break; } case MODEM_BPSK: @@ -1536,35 +1301,32 @@ static void RadioSend( uint8_t *buffer, uint8_t size ) } case MODEM_SIGFOX_TX: { - uint8_t outBuffer[35] = {0}; - /*from bpsk to dbpsk*/ - /*first 1 bit duplicated*/ - payload_integration( outBuffer, buffer, size ); + /* from bpsk to dbpsk */ + /* first 1 bit duplicated */ + /* RadioBuffer is 1 bytes more */ + payload_integration( RadioBuffer, buffer, size ); SubgRf.PacketParams.PacketType = PACKET_TYPE_BPSK; SubgRf.PacketParams.Params.Bpsk.PayloadLength = size + 1; SUBGRF_SetPacketParams( &SubgRf.PacketParams ); + RadioWrite( 0x00F1, 0 ); // clean start-up LSB + RadioWrite( 0x00F0, 0 ); // clean start-up MSB if( SubgRf.ModulationParams.Params.Bpsk.BitRate == 100 ) { - RadioWrite( 0x00F1, 0 ); // clean start-up LSB - RadioWrite( 0x00F0, 0 ); // clean start-up MSB RadioWrite( 0x00F3, 0x70 ); // clean end of frame LSB RadioWrite( 0x00F2, 0x1D ); // clean end of frame MSB } else // 600 bps { - RadioWrite( 0x00F1, 0 ); // clean start-up LSB - RadioWrite( 0x00F0, 0 ); // clean start-up MSB RadioWrite( 0x00F3, 0xE1 ); // clean end of frame LSB RadioWrite( 0x00F2, 0x04 ); // clean end of frame MSB } - uint16_t bitNum = (size*8)+2; + uint16_t bitNum = ( size * 8 ) + 2; RadioWrite( 0x00F4, ( bitNum >> 8 ) & 0x00FF ); // limit frame RadioWrite( 0x00F5, bitNum & 0x00FF ); // limit frame - // - SUBGRF_SendPayload( outBuffer, size+1 , 0xFFFFFF ); + SUBGRF_SendPayload( RadioBuffer, size+1 , 0xFFFFFF ); break; } default: @@ -1592,11 +1354,17 @@ static void RadioStandby( void ) static void RadioRx( uint32_t timeout ) { - /* Radio IRQ is set to DIO1 by default */ - SUBGRF_SetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, - IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, - IRQ_RADIO_NONE, - IRQ_RADIO_NONE ); + if ( 1UL == RFW_Is_Init( ) ) + { + RFW_ReceiveInit( ); + } + else + { + SUBGRF_SetDioIrqParams( IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR | IRQ_HEADER_ERROR | IRQ_RX_DBG, + IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR | IRQ_HEADER_ERROR | IRQ_RX_DBG, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + } if( timeout != 0 ) { @@ -1624,19 +1392,26 @@ static void RadioRx( uint32_t timeout ) static void RadioRxBoosted( uint32_t timeout ) { - SUBGRF_SetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, - IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, - IRQ_RADIO_NONE, - IRQ_RADIO_NONE ); - + if (1UL==RFW_Is_Init()) + { + RFW_ReceiveInit(); + } + else + { + SUBGRF_SetDioIrqParams( IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR | IRQ_HEADER_ERROR | IRQ_RX_DBG, + IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR | IRQ_HEADER_ERROR | IRQ_RX_DBG, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + } if( timeout != 0 ) { - TimerSetValue( &RxTimeoutTimer, timeout ); - TimerStart( &RxTimeoutTimer ); + TimerSetValue( &RxTimeoutTimer, timeout ); + TimerStart( &RxTimeoutTimer ); } /* RF switch configuration */ SUBGRF_SetSwitch(SubgRf.AntSwitchPaSelect, RFSWITCH_RX); + if( SubgRf.RxContinuous == true ) { SUBGRF_SetRxBoosted( 0xFFFFFF ); // Rx Continuous @@ -1651,18 +1426,25 @@ static void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) { /* RF switch configuration */ SUBGRF_SetSwitch(SubgRf.AntSwitchPaSelect, RFSWITCH_RX); + SUBGRF_SetRxDutyCycle( rxTime, sleepTime ); } static void RadioStartCad( void ) { - SUBGRF_SetDioIrqParams( IRQ_CAD_CLEAR | IRQ_CAD_DETECTED, IRQ_CAD_CLEAR | IRQ_CAD_DETECTED, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); + /* RF switch configuration */ + SUBGRF_SetSwitch(SubgRf.AntSwitchPaSelect, RFSWITCH_RX); + + SUBGRF_SetDioIrqParams( IRQ_CAD_CLEAR | IRQ_CAD_DETECTED, + IRQ_CAD_CLEAR | IRQ_CAD_DETECTED, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); SUBGRF_SetCad( ); } static void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ) { - uint32_t timeout = (uint32_t)time * 1000; + uint32_t timeout = ( uint32_t )time * 1000; uint8_t antswitchpow; SUBGRF_SetRfFrequency( freq ); @@ -1727,25 +1509,34 @@ static void RadioSetPublicNetwork( bool enable ) RadioSetModem( MODEM_LORA ); if( enable == true ) { - /* Change LoRa modem SyncWord */ - SUBGRF_WriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF ); - SUBGRF_WriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF ); + // Change LoRa modem SyncWord + SUBGRF_WriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF ); + SUBGRF_WriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF ); } else { - /* Change LoRa modem SyncWord */ - SUBGRF_WriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF ); - SUBGRF_WriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF ); + // Change LoRa modem SyncWord + SUBGRF_WriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF ); + SUBGRF_WriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF ); } } static uint32_t RadioGetWakeupTime( void ) { - return SUBGRF_GetRadioWakeUpTime() + RADIO_WAKEUP_TIME; + return SUBGRF_GetRadioWakeUpTime() + RADIO_WAKEUP_TIME; } - static void RadioOnTxTimeoutIrq( void* context ) +{ + RADIO_TX_TIMEOUT_PROCESS(); +} + +static void RadioOnRxTimeoutIrq( void* context ) +{ + RADIO_RX_TIMEOUT_PROCESS(); +} + +static void RadioOnTxTimeoutProcess( void ) { /* ST_WORKAROUND_BEGIN: Reset DBG pin */ DBG_GPIO_RADIO_TX(RST); @@ -1757,7 +1548,7 @@ static void RadioOnTxTimeoutIrq( void* context ) } } -static void RadioOnRxTimeoutIrq( void* context ) +static void RadioOnRxTimeoutProcess( void ) { /* ST_WORKAROUND_BEGIN: Reset DBG pin */ DBG_GPIO_RADIO_RX(RST); @@ -1771,210 +1562,538 @@ static void RadioOnRxTimeoutIrq( void* context ) static void RadioOnDioIrq( RadioIrqMasks_t radioIrq ) { - SubgRf.RadioIrq = radioIrq; + SubgRf.RadioIrq = radioIrq; - RadioIrqProcess(); + RADIO_IRQ_PROCESS(); } static void RadioIrqProcess( void ) { - uint8_t size; + uint8_t size = 0; + int32_t cfo = 0; - switch (SubgRf.RadioIrq) - { - case IRQ_TX_DONE: - /* ST_WORKAROUND_BEGIN: Reset DBG pin */ - DBG_GPIO_RADIO_TX(RST); - /* ST_WORKAROUND_END */ - - TimerStop( &TxTimeoutTimer ); - SUBGRF_SetStandby( STDBY_RC ); - if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) ) + switch ( SubgRf.RadioIrq ) { - RadioEvents->TxDone( ); - } - break; + case IRQ_TX_DONE: + /* ST_WORKAROUND_BEGIN: Reset DBG pin */ + DBG_GPIO_RADIO_TX(RST); + /* ST_WORKAROUND_END */ - case IRQ_RX_DONE: - /* ST_WORKAROUND_BEGIN: Reset DBG pin */ - DBG_GPIO_RADIO_RX(RST); - /* ST_WORKAROUND_END */ + TimerStop( &TxTimeoutTimer ); + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); - TimerStop( &RxTimeoutTimer ); - if( SubgRf.RxContinuous == false ) - { - //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC - SUBGRF_SetStandby( STDBY_RC ); - - // WORKAROUND - Implicit Header Mode Timeout Behavior, see DS_SX1261-2_V1.2 datasheet chapter 15.3 - // RegRtcControl = @address 0x0902 - SUBGRF_WriteRegister( 0x0902, 0x00 ); - // RegEventMask = @address 0x0944 - SUBGRF_WriteRegister( 0x0944, SUBGRF_ReadRegister( 0x0944 ) | ( 1 << 1 ) ); - // WORKAROUND END - } - SUBGRF_GetPayload( RadioRxPayload, &size , 255 ); - SUBGRF_GetPacketStatus( &(SubgRf.PacketStatus) ); - if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) ) - { - switch (SubgRf.PacketStatus.packetType) - { - case PACKET_TYPE_LORA: - RadioEvents->RxDone( RadioRxPayload, size, SubgRf.PacketStatus.Params.LoRa.RssiPkt, SubgRf.PacketStatus.Params.LoRa.SnrPkt ); + if ( RFW_Is_LongPacketModeEnabled() == 1 ) + { + RFW_DeInit_TxLongPacket( ); + } + + if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) ) + { + RadioEvents->TxDone( ); + } + break; + + case IRQ_RX_DONE: + /* ST_WORKAROUND_BEGIN: Reset DBG pin */ + DBG_GPIO_RADIO_RX(RST); + /* ST_WORKAROUND_END */ + + TimerStop( &RxTimeoutTimer ); + if( SubgRf.RxContinuous == false ) + { + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); + + // WORKAROUND - Implicit Header Mode Timeout Behavior, see DS_SX1261-2_V1.2 datasheet chapter 15.3 + // RegRtcControl = @address 0x0902 + SUBGRF_WriteRegister( 0x0902, 0x00 ); + // RegEventMask = @address 0x0944 + SUBGRF_WriteRegister( 0x0944, SUBGRF_ReadRegister( 0x0944 ) | ( 1 << 1 ) ); + // WORKAROUND END + } + SUBGRF_GetPayload( RadioBuffer, &size , 255 ); + SUBGRF_GetPacketStatus( &(SubgRf.PacketStatus) ); + if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) ) + { + switch ( SubgRf.PacketStatus.packetType ) + { + case PACKET_TYPE_LORA: + RadioEvents->RxDone( RadioBuffer, size, SubgRf.PacketStatus.Params.LoRa.RssiPkt, SubgRf.PacketStatus.Params.LoRa.SnrPkt ); + break; + default: + SUBGRF_GetCFO( SubgRf.ModulationParams.Params.Gfsk.BitRate, &cfo ); + RadioEvents->RxDone( RadioBuffer, size, SubgRf.PacketStatus.Params.Gfsk.RssiAvg, (int8_t) DIVR(cfo, 1000) ); + break; + } + } break; - default: - RadioEvents->RxDone( RadioRxPayload, size, SubgRf.PacketStatus.Params.Gfsk.RssiAvg, (int8_t)(SubgRf.PacketStatus.Params.Gfsk.FreqError) ); + + case IRQ_CAD_CLEAR: + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); + if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) + { + RadioEvents->CadDone( false ); + } + break; + case IRQ_CAD_DETECTED: + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); + if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) + { + RadioEvents->CadDone( true ); + } break; - } - } - break; - case IRQ_CRC_ERROR: - if( SubgRf.RxContinuous == false ) - { - //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC - SUBGRF_SetStandby( STDBY_RC ); - } - if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) - { - RadioEvents->RxError( ); - } - break; + case IRQ_RX_TX_TIMEOUT: + MW_LOG( TS_ON, VLEVEL_M, "IRQ_RX_TX_TIMEOUT\r\n" ); + if( SUBGRF_GetOperatingMode( ) == MODE_TX ) + { + /* ST_WORKAROUND_BEGIN: Reset DBG pin */ + DBG_GPIO_RADIO_TX(RST); + /* ST_WORKAROUND_END */ + + TimerStop( &TxTimeoutTimer ); + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); + if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) + { + RadioEvents->TxTimeout( ); + } + } + else if( SUBGRF_GetOperatingMode( ) == MODE_RX ) + { + /* ST_WORKAROUND_BEGIN: Reset DBG pin */ + DBG_GPIO_RADIO_RX(RST); + /* ST_WORKAROUND_END */ + + TimerStop( &RxTimeoutTimer ); + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + } + } + break; + + case IRQ_PREAMBLE_DETECTED: + MW_LOG( TS_ON, VLEVEL_M, "PRE OK\r\n" ); + break; + + case IRQ_SYNCWORD_VALID: + MW_LOG( TS_ON, VLEVEL_M, "SYNC OK\r\n" ); + if ( 1UL == RFW_Is_Init( ) ) + { + RFW_ReceivePayload( ); + } + break; + case IRQ_HEADER_VALID: + MW_LOG( TS_ON, VLEVEL_M, "HDR OK\r\n" ); + break; - case IRQ_CAD_CLEAR: - //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC - SUBGRF_SetStandby( STDBY_RC ); - if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) + case IRQ_HEADER_ERROR: + TimerStop( &RxTimeoutTimer ); + if( SubgRf.RxContinuous == false ) + { + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); + } + if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) + { + RadioEvents->RxTimeout( ); + MW_LOG( TS_ON, VLEVEL_M, "HDR KO\r\n" ); + } + break; + + case IRQ_CRC_ERROR: + MW_LOG( TS_ON, VLEVEL_M, "IRQ_CRC_ERROR\r\n" ); + + if( SubgRf.RxContinuous == false ) + { + //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC + SUBGRF_SetStandby( STDBY_RC ); + } + if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) + { + RadioEvents->RxError( ); + } + break; + default: + break; + } +} + +static void RadioTxPrbs( void ) +{ + SUBGRF_SetSwitch( SubgRf.AntSwitchPaSelect, RFSWITCH_TX ); + Radio.Write( SUBGHZ_PKTCTL1A, 0x2d ); // sel mode prbs9 instead of preamble + SUBGRF_SetTxInfinitePreamble( ); + SUBGRF_SetTx( 0x0fffff ); +} + +static void RadioTxCw( int8_t power ) +{ + uint8_t paselect = SUBGRF_SetRfTxPower( power ); + SUBGRF_SetSwitch( paselect, RFSWITCH_TX ); + SUBGRF_SetTxContinuousWave( ); +} + +static void payload_integration( uint8_t *outBuffer, uint8_t *inBuffer, uint8_t size ) +{ + uint8_t prevInt = 0; + uint8_t currBit; + uint8_t index_bit; + uint8_t index_byte; + uint8_t index_bit_out; + uint8_t index_byte_out; + int i = 0; + + for (i = 0; i < size; i++) { - RadioEvents->CadDone( false ); + /* reverse all inputs */ + inBuffer[i] = ~inBuffer[i]; + /* init outBuffer */ + outBuffer[i] = 0; } - break; - case IRQ_CAD_DETECTED: - //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC - SUBGRF_SetStandby( STDBY_RC ); - if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) + + for (i = 0; i < (size * 8); i++) { - RadioEvents->CadDone( true ); + /* index to take bit in inBuffer */ + index_bit = 7 - ( i % 8 ); + index_byte = i / 8; + /* index to place bit in outBuffer is shifted 1 bit right */ + index_bit_out = 7 - ( ( i + 1 ) % 8 ); + index_byte_out = ( i + 1 ) / 8; + /* extract current bit from input */ + currBit = ( inBuffer[index_byte] >> index_bit ) & 0x01; + /* integration */ + prevInt ^= currBit; + /* write result integration in output */ + outBuffer[index_byte_out] |= ( prevInt << index_bit_out ); } - break; - case IRQ_RX_TX_TIMEOUT: - if( SUBGRF_GetOperatingMode( ) == MODE_TX ) + outBuffer[size] = ( prevInt << 7 ) | ( prevInt << 6 ) | ( ( ( !prevInt ) & 0x01 ) << 5 ) ; +} + +static int32_t RadioSetRxGenericConfig( GenericModems_t modem, RxConfigGeneric_t* config, uint32_t rxContinuous, uint32_t symbTimeout ) +{ + int32_t status = 0; + uint8_t syncword[8] = {0}; + uint8_t MaxPayloadLength; + + RFW_DeInit( ); /* switch Off FwPacketDecoding by default */ + + if( rxContinuous != 0 ) { - /* ST_WORKAROUND_BEGIN: Reset DBG pin */ - DBG_GPIO_RADIO_TX(RST); - /* ST_WORKAROUND_END */ - - TimerStop( &TxTimeoutTimer ); - //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC - SUBGRF_SetStandby( STDBY_RC ); - if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) - { - RadioEvents->TxTimeout( ); - } + symbTimeout = 0; } - else if( SUBGRF_GetOperatingMode( ) == MODE_RX ) + SubgRf.RxContinuous = ( rxContinuous == 0 ) ? false : true; + + switch( modem ) { - /* ST_WORKAROUND_BEGIN: Reset DBG pin */ - DBG_GPIO_RADIO_RX(RST); - /* ST_WORKAROUND_END */ - - TimerStop( &RxTimeoutTimer ); - //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC - SUBGRF_SetStandby( STDBY_RC ); - if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) - { - RadioEvents->RxTimeout( ); - } - } - break; + case GENERIC_FSK: + if( ( config->fsk.BitRate == 0 ) || ( config->fsk.PreambleLen == 0 ) ) + { + return -1; + } + if( config->fsk.SyncWordLength > 8 ) + { + return -1; + } + else + { + for(int i = 0; i < config->fsk.SyncWordLength; i++) + { + syncword[i] = config->fsk.SyncWord[i]; + } + } - case IRQ_PREAMBLE_DETECTED: - MW_LOG( TS_ON, VLEVEL_M, "PRE OK\r\n" ); - break; + SUBGRF_SetStopRxTimerOnPreambleDetect( ( config->fsk.StopTimerOnPreambleDetect == 0 ) ? false : true ); - case IRQ_SYNCWORD_VALID: + SubgRf.ModulationParams.PacketType = PACKET_TYPE_GFSK; + SubgRf.ModulationParams.Params.Gfsk.BitRate = config->fsk.BitRate; + SubgRf.ModulationParams.Params.Gfsk.ModulationShaping = (RadioModShapings_t) config->fsk.ModulationShaping; + SubgRf.ModulationParams.Params.Gfsk.Bandwidth = SUBGRF_GetFskBandwidthRegValue( config->fsk.Bandwidth ); - MW_LOG( TS_ON, VLEVEL_M, "SYNC OK\r\n" ); - break; + SubgRf.PacketParams.PacketType = PACKET_TYPE_GFSK; + SubgRf.PacketParams.Params.Gfsk.PreambleLength = ( config->fsk.PreambleLen ) << 3 ; // convert byte into bit + SubgRf.PacketParams.Params.Gfsk.PreambleMinDetect = ( RadioPreambleDetection_t ) config->fsk.PreambleMinDetect; + SubgRf.PacketParams.Params.Gfsk.SyncWordLength = ( config->fsk.SyncWordLength ) << 3; // convert byte into bit + SubgRf.PacketParams.Params.Gfsk.AddrComp = ( RadioAddressComp_t ) config->fsk.AddrComp; - case IRQ_HEADER_VALID: + if( config->fsk.LengthMode == RADIO_FSK_PACKET_FIXED_LENGTH ) + { + SubgRf.PacketParams.Params.Gfsk.PayloadLength = config->fsk.MaxPayloadLength; + } + else if( config->fsk.LengthMode == RADIO_FSK_PACKET_2BYTES_LENGTH ) + { + /* Set max in the radio, in long packet mode will be tuned based dynamically on received chunk */ + SubgRf.PacketParams.Params.Gfsk.PayloadLength = 0xFF; + } + else + { + /* Set max in the radio */ + SubgRf.PacketParams.Params.Gfsk.PayloadLength = 0xFF; + } - MW_LOG( TS_ON, VLEVEL_M, "HDR OK\r\n" ); - break; + if( ( config->fsk.Whitening == RADIO_FSK_DC_IBM_WHITENING ) || ( config->fsk.LengthMode == RADIO_FSK_PACKET_2BYTES_LENGTH ) ) + { + /* Supports only RADIO_FSK_CRC_2_BYTES_IBM or RADIO_FSK_CRC_2_BYTES_CCIT*/ + if( ( config->fsk.CrcLength != RADIO_FSK_CRC_2_BYTES_IBM ) && ( config->fsk.CrcLength != RADIO_FSK_CRC_2_BYTES_CCIT ) && ( config->fsk.CrcLength != RADIO_FSK_CRC_OFF ) ) + { + return -1; + } + ConfigGeneric_t ConfigGeneric; + ConfigGeneric.rtx = CONFIG_RX; + ConfigGeneric.RxConfig = config; + if( 0UL != RFW_Init( &ConfigGeneric, RadioEvents, &RxTimeoutTimer ) ) + { + return -1; + } + /* Whitening off, will be processed by FW, switch off built-in radio whitening*/ + SubgRf.PacketParams.Params.Gfsk.DcFree = ( RadioDcFree_t ) RADIO_FSK_DC_FREE_OFF; + /* Crc off, Crc processed by FW, switch off built-in radio Crc*/ + SubgRf.PacketParams.Params.Gfsk.CrcLength = ( RadioCrcTypes_t ) RADIO_CRC_OFF; + /* Length contained in Tx, but will be processed by FW after de-whitening*/ + SubgRf.PacketParams.Params.Gfsk.HeaderType = ( RadioPacketLengthModes_t ) RADIO_PACKET_FIXED_LENGTH; + } + else + { + SubgRf.PacketParams.Params.Gfsk.CrcLength = ( RadioCrcTypes_t ) config->fsk.CrcLength; + SubgRf.PacketParams.Params.Gfsk.DcFree = ( RadioDcFree_t ) config->fsk.Whitening; + SubgRf.PacketParams.Params.Gfsk.HeaderType = ( RadioPacketLengthModes_t ) config->fsk.LengthMode; + } - case IRQ_HEADER_ERROR: - TimerStop( &RxTimeoutTimer ); - if( SubgRf.RxContinuous == false ) - { - //!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC - SUBGRF_SetStandby( STDBY_RC ); - } - if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) - { - RadioEvents->RxTimeout( ); - MW_LOG( TS_ON, VLEVEL_M, "HDR KO\r\n" ); - } - break; + RadioStandby( ); + RadioSetModem( MODEM_FSK ); + SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); + SUBGRF_SetPacketParams( &SubgRf.PacketParams ); + SUBGRF_SetSyncWord( syncword ); + SUBGRF_SetWhiteningSeed( config->fsk.whiteSeed ); + SUBGRF_SetCrcPolynomial( config->fsk.CrcPolynomial ); + /* timeout unused when SubgRf.RxContinuous */ + SubgRf.RxTimeout = ( uint32_t )( ( symbTimeout * 1000 * 8 ) / config->fsk.BitRate ); + break; + case GENERIC_LORA: + if( config->lora.PreambleLen == 0 ) + { + return -1; + } - default: - break; + if( config->lora.LengthMode == RADIO_LORA_PACKET_FIXED_LENGTH ) + { + MaxPayloadLength = config->fsk.MaxPayloadLength; + } + else + { + MaxPayloadLength = 0xFF; + } + SUBGRF_SetStopRxTimerOnPreambleDetect( ( config->lora.StopTimerOnPreambleDetect == 0 ) ? false : true ); + SUBGRF_SetLoRaSymbNumTimeout( symbTimeout ); + + SubgRf.ModulationParams.PacketType = PACKET_TYPE_LORA; + SubgRf.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) config->lora.SpreadingFactor; + SubgRf.ModulationParams.Params.LoRa.Bandwidth = ( RadioLoRaBandwidths_t ) config->lora.Bandwidth; + SubgRf.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t ) config->lora.Coderate; + switch( config->lora.LowDatarateOptimize ) + { + case RADIO_LORA_LOWDR_OPT_OFF: + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; + break; + case RADIO_LORA_LOWDR_OPT_ON: + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; + break; + case RADIO_LORA_LOWDR_OPT_AUTO: + if( ( config->lora.SpreadingFactor == RADIO_LORA_SF11 ) || ( config->lora.SpreadingFactor == RADIO_LORA_SF12 ) ) + { + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; + } + else + { + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; + } + break; + default: + break; + } - } -} + SubgRf.PacketParams.PacketType = PACKET_TYPE_LORA; + SubgRf.PacketParams.Params.LoRa.PreambleLength = config->lora.PreambleLen; + SubgRf.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t ) config->lora.LengthMode; + SubgRf.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; + SubgRf.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t ) config->lora.CrcMode; + SubgRf.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t ) config->lora.IqInverted; -static void RadioTxPrbs(void ) -{ - SUBGRF_SetSwitch(SubgRf.AntSwitchPaSelect, RFSWITCH_TX); - Radio.Write(0x6B8, 0x2d); // sel mode prbs9 instead of preamble - SUBGRF_SetTxInfinitePreamble(); - SUBGRF_SetTx(0x0fffff); -} + RadioStandby( ); + RadioSetModem( MODEM_LORA ); + SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); + SUBGRF_SetPacketParams( &SubgRf.PacketParams ); -static void RadioTxCw( int8_t power ) -{ - uint8_t paselect = SUBGRF_SetRfTxPower( power ); - SUBGRF_SetSwitch( paselect, RFSWITCH_TX); - SUBGRF_SetTxContinuousWave(); + // WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4 + if( SubgRf.PacketParams.Params.LoRa.InvertIQ == LORA_IQ_INVERTED ) + { + // RegIqPolaritySetup = @address 0x0736 + SUBGRF_WriteRegister( 0x0736, SUBGRF_ReadRegister( 0x0736 ) & ~( 1 << 2 ) ); + } + else + { + // RegIqPolaritySetup @address 0x0736 + SUBGRF_WriteRegister( 0x0736, SUBGRF_ReadRegister( 0x0736 ) | ( 1 << 2 ) ); + } + // WORKAROUND END + + // Timeout Max, Timeout handled directly in SetRx function + SubgRf.RxTimeout = 0xFFFF; + break; + default: + break; + } + return status; } -static void payload_integration( uint8_t *outBuffer, uint8_t *inBuffer, uint8_t size) +static int32_t RadioSetTxGenericConfig( GenericModems_t modem, TxConfigGeneric_t* config, int8_t power, uint32_t timeout ) { - uint8_t prevInt=0; - uint8_t currBit; - uint8_t index_bit; - uint8_t index_byte; - uint8_t index_bit_out; - uint8_t index_byte_out; - int i=0; - - for (i=0; ifsk.BitRate == 0 ) || ( config->fsk.PreambleLen == 0 ) ) + { + return -1; + } + if( config->fsk.SyncWordLength > 8 ) + { + return -1; + } + else + { + for(int i = 0; i < config->fsk.SyncWordLength; i++) + { + syncword[i] = config->fsk.SyncWord[i]; + } + } + SubgRf.ModulationParams.PacketType = PACKET_TYPE_GFSK; + SubgRf.ModulationParams.Params.Gfsk.BitRate = config->fsk.BitRate; + SubgRf.ModulationParams.Params.Gfsk.ModulationShaping = ( RadioModShapings_t ) config->fsk.ModulationShaping; + SubgRf.ModulationParams.Params.Gfsk.Bandwidth = SUBGRF_GetFskBandwidthRegValue( config->fsk.Bandwidth ); + SubgRf.ModulationParams.Params.Gfsk.Fdev = config->fsk.FrequencyDeviation; + + SubgRf.PacketParams.PacketType = PACKET_TYPE_GFSK; + SubgRf.PacketParams.Params.Gfsk.PreambleLength = ( config->fsk.PreambleLen ) << 3; // convert byte into bit + SubgRf.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; // don't care in tx + SubgRf.PacketParams.Params.Gfsk.SyncWordLength = ( config->fsk.SyncWordLength ) << 3; // convert byte into bit + SubgRf.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; // don't care in tx + + if( ( config->fsk.Whitening == RADIO_FSK_DC_IBM_WHITENING ) || ( config->fsk.HeaderType == RADIO_FSK_PACKET_2BYTES_LENGTH ) ) + { + /* Supports only RADIO_FSK_CRC_2_BYTES_IBM or RADIO_FSK_CRC_2_BYTES_CCIT */ + if( ( config->fsk.CrcLength != RADIO_FSK_CRC_2_BYTES_IBM ) && ( config->fsk.CrcLength != RADIO_FSK_CRC_2_BYTES_CCIT ) &&( config->fsk.CrcLength != RADIO_FSK_CRC_OFF ) ) + { + return -1; + } + ConfigGeneric_t ConfigGeneric; + ConfigGeneric.rtx = CONFIG_TX; + ConfigGeneric.TxConfig = config; + if( 0UL != RFW_Init( &ConfigGeneric, RadioEvents, &TxTimeoutTimer ) ) + { + return -1; + } + /* whitening off, will be processed by FW, switch off built-in radio whitening */ + SubgRf.PacketParams.Params.Gfsk.DcFree = ( RadioDcFree_t ) RADIO_FSK_DC_FREE_OFF; + /* Crc processed by FW, switch off built-in radio Crc */ + SubgRf.PacketParams.Params.Gfsk.CrcLength = (RadioCrcTypes_t) RADIO_CRC_OFF; + /* length contained in Tx, but will be processed by FW after de-whitening */ + SubgRf.PacketParams.Params.Gfsk.HeaderType = ( RadioPacketLengthModes_t ) RADIO_PACKET_FIXED_LENGTH; + } + else + { + SubgRf.PacketParams.Params.Gfsk.CrcLength = ( RadioCrcTypes_t ) config->fsk.CrcLength; + SubgRf.PacketParams.Params.Gfsk.DcFree = ( RadioDcFree_t ) config->fsk.Whitening; + SubgRf.PacketParams.Params.Gfsk.HeaderType = ( RadioPacketLengthModes_t ) config->fsk.HeaderType; + } - for (i=0; i> index_bit) & 0x01; - /*integration*/ - prevInt ^= currBit; - /* write result integration in output*/ - outBuffer[index_byte_out]|= (prevInt << index_bit_out); - } + RadioStandby( ); + RadioSetModem( MODEM_FSK ); + SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); + SUBGRF_SetPacketParams( &SubgRf.PacketParams ); + SUBGRF_SetSyncWord( syncword ); + SUBGRF_SetWhiteningSeed( config->fsk.whiteSeed ); + SUBGRF_SetCrcPolynomial(config->fsk.CrcPolynomial ); + break; + case GENERIC_LORA: + SubgRf.ModulationParams.PacketType = PACKET_TYPE_LORA; + SubgRf.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) config->lora.SpreadingFactor; + SubgRf.ModulationParams.Params.LoRa.Bandwidth = ( RadioLoRaBandwidths_t ) config->lora.Bandwidth; + SubgRf.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t ) config->lora.Coderate; + switch( config->lora.LowDatarateOptimize ) + { + case RADIO_LORA_LOWDR_OPT_OFF: + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; + break; + case RADIO_LORA_LOWDR_OPT_ON: + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; + break; + case RADIO_LORA_LOWDR_OPT_AUTO: + if( ( config->lora.SpreadingFactor == RADIO_LORA_SF11 ) || ( config->lora.SpreadingFactor == RADIO_LORA_SF12 ) ) + { + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 1; + } + else + { + SubgRf.ModulationParams.Params.LoRa.LowDatarateOptimize = 0; + } + break; + default: + break; + } + + SubgRf.PacketParams.PacketType = PACKET_TYPE_LORA; + SubgRf.PacketParams.Params.LoRa.PreambleLength = config->lora.PreambleLen; + SubgRf.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t ) config->lora.LengthMode; + SubgRf.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t ) config->lora.CrcMode; + SubgRf.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t ) config->lora.IqInverted; + + RadioStandby( ); + RadioSetModem( MODEM_LORA ); + SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); + SUBGRF_SetPacketParams( &SubgRf.PacketParams ); + // WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1 + if( SubgRf.ModulationParams.Params.LoRa.Bandwidth == LORA_BW_500 ) + { + // RegTxModulation = @address 0x0889 + SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) & ~( 1 << 2 ) ); + } + else + { + // RegTxModulation = @address 0x0889 + SUBGRF_WriteRegister( 0x0889, SUBGRF_ReadRegister( 0x0889 ) | ( 1 << 2 ) ); + } + // WORKAROUND END + break; + case GENERIC_BPSK: + if( ( config->bpsk.BitRate == 0 ) || ( config->bpsk.BitRate > 1000 ) ) + { + return -1; + } + RadioSetModem( MODEM_BPSK ); + SubgRf.ModulationParams.PacketType = PACKET_TYPE_BPSK; + SubgRf.ModulationParams.Params.Bpsk.BitRate = config->bpsk.BitRate; + SubgRf.ModulationParams.Params.Bpsk.ModulationShaping = MOD_SHAPING_DBPSK; + SUBGRF_SetModulationParams( &SubgRf.ModulationParams ); + break; + default: + break; + } - outBuffer[size] =(prevInt<<7) | (prevInt<<6) | (( (!prevInt) & 0x01)<<5) ; + SubgRf.AntSwitchPaSelect = SUBGRF_SetRfTxPower( power ); + RFW_SetAntSwitch( SubgRf.AntSwitchPaSelect ); + SubgRf.TxTimeout = timeout; + return 0; } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c index bde74954..b7288929 100644 --- a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c +++ b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.c @@ -31,10 +31,9 @@ ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ -#include "radio_driver.h" #include "radio_conf.h" +#include "radio_driver.h" #include "mw_log_conf.h" -#include "stm32_lpm.h" /* External variables ---------------------------------------------------------*/ /*! @@ -44,26 +43,73 @@ extern SUBGHZ_HandleTypeDef hsubghz; /* Private typedef -----------------------------------------------------------*/ /*! - * \brief Radio registers definition + * FSK bandwidth definition */ -typedef struct +typedef struct FskBandwidth_s { - uint16_t Addr; //!< The address of the register - uint8_t Value; //!< The value of the register -}RadioRegisters_t; - + uint32_t bandwidth; + uint8_t RegValue; +} FskBandwidth_t; /* Private define ------------------------------------------------------------*/ +/** + * @brief drive value used anytime radio is NOT in TX low power mode + * @note SMPS_DRIVE_SETTING_DEFAULT can be redefined in radio_conf.h + */ +#ifndef SMPS_DRIVE_SETTING_DEFAULT +#define SMPS_DRIVE_SETTING_DEFAULT SMPS_DRV_40 +#endif /* SMPS_DRIVE_SETTING_DEFAULT */ -/*! - * \brief Provides the frequency of the chip running on the radio and the frequency step - * - * \remark These defines are used for computing the frequency divider to set the RF frequency - * - * \note XTAL_FREQ can be redefined in radio_conf.h - */ +/** + * @brief drive value used anytime radio is in TX low power mode + * TX low power mode is the worst case because the PA sinks from SMPS + * while in high power mode, current is sunk directly from the battery + * @note SMPS_DRIVE_SETTING_MAX can be redefined in radio_conf.h + */ +#ifndef SMPS_DRIVE_SETTING_MAX +#define SMPS_DRIVE_SETTING_MAX SMPS_DRV_60 +#endif /* SMPS_DRIVE_SETTING_MAX */ + +/** + * @brief Provides the frequency of the chip running on the radio and the frequency step + * @remark These defines are used for computing the frequency divider to set the RF frequency + * @note XTAL_FREQ can be redefined in radio_conf.h + */ #ifndef XTAL_FREQ -#define XTAL_FREQ 32000000UL -#endif +#define XTAL_FREQ ( 32000000UL ) +#endif /* XTAL_FREQ */ + +/** + * @brief in XO mode, set internal capacitor (from 0x00 to 0x2F starting 11.2pF with 0.47pF steps) + * @note XTAL_DEFAULT_CAP_VALUE can be redefined in radio_conf.h + */ +#ifndef XTAL_DEFAULT_CAP_VALUE +#define XTAL_DEFAULT_CAP_VALUE ( 0x20UL ) +#endif /* XTAL_DEFAULT_CAP_VALUE */ + +/** + * @brief voltage of vdd tcxo. + * @note TCXO_CTRL_VOLTAGE can be redefined in radio_conf.h + */ +#ifndef TCXO_CTRL_VOLTAGE +#define TCXO_CTRL_VOLTAGE TCXO_CTRL_1_7V +#endif /* TCXO_CTRL_VOLTAGE */ + +/** + * @brief Radio maximum wakeup time (in ms) + * @note RF_WAKEUP_TIME can be redefined in radio_conf.h + */ +#ifndef RF_WAKEUP_TIME +#define RF_WAKEUP_TIME ( 10UL ) +#endif /* RF_WAKEUP_TIME */ + +/** + * @brief DCDC is present and enabled + * @remark this define is only used if the DCDC is present on the board + * @note DCDC_ENABLE can be redefined in radio_conf.h + */ +#ifndef DCDC_ENABLE +#define DCDC_ENABLE ( 1UL ) +#endif /* DCDC_ENABLE */ /* Private macro -------------------------------------------------------------*/ @@ -73,9 +119,6 @@ do \ channel = (uint32_t) ((((uint64_t) freq)<<25)/(XTAL_FREQ) ); \ }while( 0 ) -#define SUBGRF_WriteCommand( x, y, z ) HAL_SUBGHZ_ExecSetCmd( &hsubghz, (x), (y), (z) ) -#define SUBGRF_ReadCommand( x, y, z ) HAL_SUBGHZ_ExecGetCmd( &hsubghz, (x), (y), (z) ) - /* Private variables ---------------------------------------------------------*/ /*! * \brief Holds the internal operating mode of the radio @@ -102,6 +145,35 @@ volatile uint32_t FrequencyError = 0; */ static bool ImageCalibrated = false; +/*! + * Precomputed FSK bandwidth registers values + */ +static const FskBandwidth_t FskBandwidths[] = +{ + { 4800 , 0x1F }, + { 5800 , 0x17 }, + { 7300 , 0x0F }, + { 9700 , 0x1E }, + { 11700 , 0x16 }, + { 14600 , 0x0E }, + { 19500 , 0x1D }, + { 23400 , 0x15 }, + { 29300 , 0x0D }, + { 39000 , 0x1C }, + { 46900 , 0x14 }, + { 58600 , 0x0C }, + { 78200 , 0x1B }, + { 93800 , 0x13 }, + { 117300, 0x0B }, + { 156200, 0x1A }, + { 187200, 0x12 }, + { 234300, 0x0A }, + { 312000, 0x19 }, + { 373600, 0x11 }, + { 467000, 0x09 }, + { 500000, 0x00 }, // Invalid Bandwidth +}; + /* Private function prototypes -----------------------------------------------*/ /*! @@ -114,6 +186,25 @@ static void Radio_SMPS_Set( uint8_t level ); */ static DioIrqHandler RadioOnDioIrqCb; +/*! + * \brief Write command to the radio + * + * \param [in] SetCommand The Write Command + * \param [out] buffer A pointer command buffer + * \param [in] size Size in byte of the command buffer + */ +static void SUBGRF_WriteCommand( SUBGHZ_RadioSetCmd_t Command, uint8_t *pBuffer, + uint16_t Size ); +/*! + * \brief Read command to the radio + * + * \param [in] GetCommand The Read Command + * \param [out] buffer A pointer command buffer + * \param [in] size Size in byte of the command buffer + */ +static void SUBGRF_ReadCommand( SUBGHZ_RadioGetCmd_t Command, uint8_t *pBuffer, + uint16_t Size ); + /* Exported functions ---------------------------------------------------------*/ void SUBGRF_Init( DioIrqHandler dioIrq ) { @@ -122,11 +213,11 @@ void SUBGRF_Init( DioIrqHandler dioIrq ) RadioOnDioIrqCb = dioIrq; } + RADIO_INIT(); + /* set default SMPS current drive to default*/ Radio_SMPS_Set(SMPS_DRIVE_SETTING_DEFAULT); - RADIO_INIT(); - ImageCalibrated = false; SUBGRF_SetStandby( STDBY_RC ); @@ -134,7 +225,7 @@ void SUBGRF_Init( DioIrqHandler dioIrq ) // Initialize TCXO control if (1U == RBI_IsTCXO() ) { - SUBGRF_SetTcxoMode( TCXO_CTRL_VOLTAGE, RBI_GetWakeUpTime() << 6 );// 100 ms + SUBGRF_SetTcxoMode( TCXO_CTRL_VOLTAGE, RF_WAKEUP_TIME << 6 );// 100 ms SUBGRF_WriteRegister( REG_XTA_TRIM, 0x00 ); /*enable calibration for cut1.1 and later*/ @@ -173,6 +264,7 @@ uint8_t SUBGRF_GetPayload( uint8_t *buffer, uint8_t *size, uint8_t maxSize ) return 1; } SUBGRF_ReadBuffer( offset, buffer, *size ); + return 0; } @@ -401,7 +493,7 @@ void SUBGRF_SetRegulatorMode( void ) /* ST_WORKAROUND_BEGIN: Get RegulatorMode value from RBI */ RadioRegulatorMode_t mode; - if ( 1U == RBI_IsDCDC() ) + if ( ( 1UL == RBI_IsDCDC() ) && ( 1UL == DCDC_ENABLE ) ) { mode = USE_DCDC ; } @@ -514,8 +606,6 @@ void SUBGRF_SetRfFrequency( uint32_t frequency ) uint8_t buf[4]; uint32_t chan = 0; - frequency+= RF_FREQUENCY_ERROR; - if( ImageCalibrated == false ) { SUBGRF_CalibrateImage( frequency ); @@ -871,22 +961,46 @@ uint8_t SUBGRF_ReadRegister( uint16_t addr ) void SUBGRF_WriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) { + CRITICAL_SECTION_BEGIN(); HAL_SUBGHZ_WriteRegisters( &hsubghz, address, buffer, size ); + CRITICAL_SECTION_END(); } void SUBGRF_ReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) { + CRITICAL_SECTION_BEGIN(); HAL_SUBGHZ_ReadRegisters( &hsubghz, address, buffer, size ); + CRITICAL_SECTION_END(); } void SUBGRF_WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) { + CRITICAL_SECTION_BEGIN(); HAL_SUBGHZ_WriteBuffer( &hsubghz, offset, buffer, size ); + CRITICAL_SECTION_END(); } void SUBGRF_ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) { + CRITICAL_SECTION_BEGIN(); HAL_SUBGHZ_ReadBuffer( &hsubghz, offset, buffer, size ); + CRITICAL_SECTION_END(); +} + +void SUBGRF_WriteCommand( SUBGHZ_RadioSetCmd_t Command, uint8_t *pBuffer, + uint16_t Size ) +{ + CRITICAL_SECTION_BEGIN(); + HAL_SUBGHZ_ExecSetCmd( &hsubghz, Command, pBuffer, Size ); + CRITICAL_SECTION_END(); +} + +void SUBGRF_ReadCommand( SUBGHZ_RadioGetCmd_t Command, uint8_t *pBuffer, + uint16_t Size ) +{ + CRITICAL_SECTION_BEGIN(); + HAL_SUBGHZ_ExecGetCmd( &hsubghz, Command, pBuffer, Size ); + CRITICAL_SECTION_END(); } void SUBGRF_SetSwitch( uint8_t paSelect, RFState_t rxtx ) @@ -956,7 +1070,7 @@ uint8_t SUBGRF_SetRfTxPower( int8_t power ) uint32_t SUBGRF_GetRadioWakeUpTime( void ) { - return ( uint32_t ) RBI_GetWakeUpTime(); + return RF_WAKEUP_TIME; } /* HAL_SUBGHz Callbacks definitions */ @@ -1025,4 +1139,59 @@ static void Radio_SMPS_Set(uint8_t level) SUBGRF_WriteRegister(SUBGHZ_SMPSC2R, modReg | level); } } + +uint8_t SUBGRF_GetFskBandwidthRegValue( uint32_t bandwidth ) +{ + uint8_t i; + + if( bandwidth == 0 ) + { + return( 0x1F ); + } + + /* ST_WORKAROUND_BEGIN: Simplified loop */ + for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ); i++ ) + { + if ( bandwidth < FskBandwidths[i].bandwidth ) + { + return FskBandwidths[i].RegValue; + } + } + /* ST_WORKAROUND_END */ + // ERROR: Value not found + while( 1 ); +} +void SUBGRF_GetCFO( uint32_t bitRate, int32_t *cfo) +{ + uint8_t BwMant[] = {4, 8, 10, 12}; + /* read demod bandwidth: mant bit4:3, exp bits 2:0 */ + uint8_t reg = (SUBGRF_ReadRegister( SUBGHZ_BWSEL )); + uint8_t bandwidth_mant = BwMant[( reg >> 3 ) & 0x3]; + uint8_t bandwidth_exp = reg & 0x7; + uint32_t cf_fs = XTAL_FREQ / ( bandwidth_mant * ( 1 << ( bandwidth_exp - 1 ))); + uint32_t cf_osr = cf_fs / bitRate; + uint8_t interp = 1; + /* calculate demod interpolation factor */ + if (cf_osr * interp < 8) + { + interp = 2; + } + if (cf_osr * interp < 4) + { + interp = 4; + } + /* calculate demod sampling frequency */ + uint32_t fs = cf_fs* interp; + /* get the cfo registers */ + int32_t cfo_bin = ( SUBGRF_ReadRegister( SUBGHZ_CFO_H ) & 0xF ) << 8; + cfo_bin |= SUBGRF_ReadRegister( SUBGHZ_CFO_L ); + /* negate if 12 bits sign bit is 1 */ + if (( cfo_bin & 0x800 ) == 0x800 ) + { + cfo_bin |= 0xFFFFF000; + } + /* calculate cfo in Hz */ + /* shift by 5 first to not saturate, cfo_bin on 12bits */ + *cfo = ((int32_t)( cfo_bin * ( fs >> 5 ))) >> ( 12 - 5 ); +} /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.h b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.h index 46a61c76..e3f6f487 100644 --- a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.h +++ b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_driver.h @@ -241,7 +241,23 @@ extern "C" { #define SUBGHZ_PCR 0x091A /*Sub-GHz radio SMPS control 2 register */ #define SUBGHZ_SMPSC2R 0x0923 - +/*Sub-GHz radio Rx Bandwidth selector register */ +#define SUBGHZ_BWSEL 0x0807 +/*Sub-GHz radio CFO High register */ +#define SUBGHZ_CFO_H 0x06B0 +/*Sub-GHz radio CFO Low register */ +#define SUBGHZ_CFO_L 0x06B1 +/*Sub-GHz radio rxAddrPtr register*/ +#define SUBGHZ_RX_ADR_PTR 0x0803 +/*Sub-GHz radio txAddrPtr register*/ +#define SUBGHZ_TX_ADR_PTR 0x0802 +/*Sub-GHz radio rtx register*/ +#define SUBGHZ_RTXPLDLEN 0x06BB +/*Sub-GHz radio pktCtl1 register*/ +#define SUBGHZ_PKTCTL1 0x06B4 +/*Sub-GHz radio pktCtl1a register*/ +#define SUBGHZ_PKTCTL1A 0x06B8 + #define SMPS_CLK_DET_ENABLE ((uint8_t) (1<<6)) #define SMPS_DRV_20 ((uint8_t) ((0x0)<<1)) @@ -1199,6 +1215,21 @@ uint8_t SUBGRF_SetRfTxPower( int8_t power ); */ uint32_t SUBGRF_GetRadioWakeUpTime( void ); +/*! + * \brief Returns the known FSK bandwidth registers value + * + * \param [IN] bandwidth Bandwidth value in Hz + * \retval regValue Bandwidth register value. + */ +uint8_t SUBGRF_GetFskBandwidthRegValue( uint32_t bandwidth ); +/*! + * \brief SUBGRF_GetCFO get the frequency offset between the remote transmitter and the radio receiver + * + * \param [in] bitrate gfsk bitrate + * \param [OUT] cfo carrier frequency offset in Hertz + */ +void SUBGRF_GetCFO( uint32_t BitRate, int32_t * Cfo); + #ifdef __cplusplus } #endif diff --git a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_fw.c b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_fw.c new file mode 100644 index 00000000..e273380e --- /dev/null +++ b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_fw.c @@ -0,0 +1,1107 @@ +/** + ****************************************************************************** + * @file radio_fw.c + * @author MCD Application Team + * @brief extended radio functionality SubGHz_Phy Middleware + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include "timer.h" +#include "radio.h" +#include "radio_fw.h" +#include "radio_driver.h" +#include "radio_conf.h" +#include "mw_log_conf.h" + +/* External variables --------------------------------------------------------*/ +/* Private typedef -----------------------------------------------------------*/ + +/** + * Radio RFWPacket and global parameters + * In RFWPacket mode, the packet is 'Fixed length' without Hw Crc check and without Hw (de-)whitening + */ +typedef struct +{ + uint8_t Enable; /* RFWPacket mode On: 1 or Off: 0*/ + uint8_t PayloadLengthFieldSize; /* Size of the packet length Field*/ + uint8_t CrcEnable; /* enable crc calculation and check*/ + uint8_t CrcFieldSize; /* size of the packet length Field*/ + uint16_t CrcPolynomial; /* Init Crc polynomial, to set before running RFW_CrcRun*/ + uint16_t CrcSeed; /* Init Crc seed to set before running RFW_CrcRun*/ + RADIO_FSK_CrcTypes_t CrcType; /* Init Crc types to set before running RFW_CrcRun*/ + uint16_t WhiteSeed; /* Init whitening seed, to set before running Radio_FwWhiteRun*/ + uint16_t LongPacketMaxRxLength; /* Maximum expected amount of bytes in payload*/ + RadioModems_t Modem; + RadioEvents_t* RadioEvents; +} RFwInit_t; + +typedef struct +{ + RFwInit_t Init; /*Init structure, set at Rx or Tx config*/ + uint16_t CrcLfsrState; /*State of LFSR crc, set from CrcSeed at beginning of each payload*/ + uint16_t WhiteLfsrState; /*State of LFSR whitening, set from WhiteSeed at beginning of each payload + use to save LFSR state after rx payload length de-withening*/ + uint16_t PayloadLength; /*In Rx, Payload length is first byte(s) of the payload excluding CrcFieldSize and PayloadLengthFieldSize*/ + uint8_t LongPacketModeEnable; /* set to one when RFW_TransmitLongPacket or RFW_ReceiveLongPacket. 0 otherwise*/ + TimerEvent_t Timer; /*Timer to get/Set Rx(Tx)Bytes*/ + uint16_t LongPacketRemainingBytes; /* Count remaining bytes to send receive (including crc)*/ + uint8_t RadioBufferOffset; /* Radio buffer offset*/ + uint16_t RxPayloadOffset; /* RxPayloadOffset buffer offset*/ + void (*RxLongPacketStoreChunkCb) (uint8_t* buffer, uint8_t buffer_size); + void (*TxLongPacketGetNextChunkCb) (uint8_t** buffer, uint8_t buffer_size); + uint8_t AntSwitchPaSelect; + uint32_t BitRate; + TimerEvent_t* RxTimeoutTimer; + TimerEvent_t* TxTimeoutTimer; +} RadioFw_t; + +/* Private define ------------------------------------------------------------*/ + +#define RADIO_BUF_SIZE 255 //bytes SubG IP internal Buffer + +#define LONGPACKET_CHUNK_LENGTH_BYTES ((int32_t) 128) //bytes (half Radio fifo) + +/* Private macro -------------------------------------------------------------*/ +/** + * @brief Calculates ceiling division of ( X / N ) + * + * @param [IN] X numerator + * @param [IN] N denominator + * + */ +#ifndef DIVC +#define DIVC( X, N ) ( ( ( X ) + ( N ) - 1 ) / ( N ) ) +#endif + +/** + * @brief Calculates rounding division of ( X / N ) + * + * @param [IN] X numerator + * @param [IN] N denominator + * + */ +#ifndef DIVR +#define DIVR( X, N ) ( ( ( X ) + ( ((X)>0?(N):(N))>>1 ) ) / ( N ) ) +#endif + +/*can be overridden in radio_conf.h*/ +#ifndef RFW_IT_INIT +#define RFW_IT_INIT() +#endif + +#ifndef RFW_GET_PAYLOAD_PROCESS +#define RFW_GET_PAYLOAD_PROCESS() RFW_GetPayloadProcess() +#endif +/*can be overridden in radio_conf.h*/ +#ifndef RFW_TRANSMIT_LONGPACKET_TX_CHUNK_PROCESS +#define RFW_TRANSMIT_LONGPACKET_TX_CHUNK_PROCESS() RFW_TransmitLongPacket_TxChunkProcess() +#endif + +#ifndef RFW_MW_LOG_ENABLE +#define RFW_MW_LOG(...) +#else +#define RFW_MW_LOG MW_LOG +#endif + +#ifndef RFW_ENABLE +#define RFW_ENABLE 0 +#endif + +#ifndef RFW_LONGPACKET_ENABLE +#define RFW_LONGPACKET_ENABLE 0 +#endif + +#ifndef RADIO_MEMCPY8 +#define RADIO_MEMCPY8 memcpy +#endif + +#ifndef RADIO_MEMSET8 +#define RADIO_MEMSET8 memset +#endif + +#if ((RFW_LONGPACKET_ENABLE==1)&&(RFW_ENABLE==0)) +#error RFW_ENABLE must be defined to 1 if RFW_LONGPACKET_ENABLE is defined to 1 +#endif + +/* Private variables ---------------------------------------------------------*/ +#if (RFW_ENABLE ==1 ) +static RadioFw_t RFWPacket={0}; +/*Radio buffer chunk*/ +static uint8_t ChunkBuffer[RADIO_BUF_SIZE]; +/*Radio buffer chunk for packet <=RADIO_BUF_SIZE and */ +static uint8_t RxBuffer[RADIO_BUF_SIZE]; +#endif +/* Private function prototypes -----------------------------------------------*/ +#if (RFW_ENABLE ==1 ) +/** + * @brief Record the seed of the (de-)Whitening algorithm + * + * @param [IN] RFwInit_t the whitening Init structure + * @param [IN] WhiteSeed the Initial seed of the Whitening algorithm + */ +static void RFW_WhiteInitState(RFwInit_t* Init, uint16_t WhiteSeed); + +/** + * @brief Set the state of the Whitening algorithm from the seed + * + * @param [IN] RFWPacket the whitening structure + * @param [IN] whiteSeed the Initial seed of the Whitening algorithm + */ +static void RFW_WhiteSetState(RadioFw_t* RFWPacket); + +/** + * @brief Initialize seed of the Crc algorithm + * + * @param [IN] RFWPacket the whitening Init structure + * @param [IN] CrcPolynomial the Initial seed of the Crc algorithm + * @param [IN] CrcSeed the Initial seed of the Crc seed + * @param [IN] CrcSeed the Initial seed of the Crc types (Ibm/CCITT) + + */ +static void RFW_CrcInitState(RFwInit_t* Init, const uint16_t CrcPolynomial, const uint16_t CrcSeed, const RADIO_FSK_CrcTypes_t CrcTypes); + +/** + * @brief Run the Crc algorithm + * @param [IN] RFWPacket the whitening structure + */ +static void RFW_CrcSetState(RadioFw_t* RFWPacket); +/** + * @brief Run the Whitening algorithm + * + * @param [IN] RFWPacket the whitening structure + * @param [IN/OUT] Payload the Payload to (de-)Whiten and the payload result + * @param [IN] Size the Payload size + */ +static void RFW_WhiteRun(RadioFw_t* RFWPacket, uint8_t* Payload, uint32_t Size); + +/** + * @brief Run the Crc algorithm + * + * @param [IN] RFWPacket the whitening structure + * @param [IN] Payload the Payload to calculate the Crc + * @param [IN] Size the Payload size + * @param [OUT] CrcResult the result of the Crc calculation + */ +static int32_t RFW_CrcRun(RadioFw_t* const RFWPacket, const uint8_t* Payload, const uint32_t Size, uint8_t CrcResult[2]); + +/** + * @brief Compute Crc Byte + * + * @param [IN] crc Crc bytes + * @param [IN] dataByte the data byte + * @param [OUT] polynomial the polynomial to use + * @return crc bytes out + */ +uint16_t RFW_CrcRun1Byte( uint16_t Crc, uint8_t DataByte, uint16_t Polynomial ); + +/** + * @brief Get the payload length after sync + * + * @param [OUT] PayloadLength the length of PayloadOnly excluding CrcLengthField + * @return 0 when no parameters error, -1 otherwise + */ +static int32_t RFW_GetPacketLength(uint16_t* PayloadLength); + +/** + * @brief RFW_GetPayloadTimerEvent TimerEvent to get the payload data, de-whitening, and crc verification + * + * @Note calls RFW_GetPayloadProcess directly inside IRQ (default) or in background with sequencer or OS + * @param [IN] context context of the timer + */ +static void RFW_GetPayloadTimerEvent( void * context); + +/** + * @brief RFW_GetPayloadProcess process to get the payload data, de-whitening, and crc verification + */ +static void RFW_GetPayloadProcess( void ); + +#if (RFW_LONGPACKET_ENABLE ==1 ) +/** + * @brief RFW_TransmitLongPacket_NewTxChunkTimer: long packet Tx timer callback to process intermediate chunk of TxData + * @Note calls RFW_TransmitLongPacket_TxChunkProcess directly inside IRQ (default) or in background with sequencer or any Rtos + * + * @param [In] param unused + */ +static void RFW_TransmitLongPacket_NewTxChunkTimerEvent( void * param ); + +/** + * @brief RFW_TransmitLongPacket_TxChunkProcess: tx long packet process intermediate chunk of TxData + */ +static void RFW_TransmitLongPacket_TxChunkProcess( void ); +#endif + +/** + * @brief RFW_GetPayload get the payload of + * + * @param [In] Offset Offset of the + * @param [In] Length carrier frequency offset in Hertz + */ +static void RFW_GetPayload( uint8_t Offset, uint8_t Length ); +#endif + +/* Exported functions --------------------------------------------------------*/ +int32_t RFW_TransmitLongPacket( uint16_t payload_size, uint32_t timeout, void (*TxLongPacketGetNextChunkCb) (uint8_t** buffer, uint8_t buffer_size) ) +{ + int32_t status=0; +#if (RFW_LONGPACKET_ENABLE ==1 ) + uint32_t total_size= payload_size+ RFWPacket.Init.PayloadLengthFieldSize+ RFWPacket.Init.CrcFieldSize; + + RFW_MW_LOG( TS_ON, VLEVEL_M, "RevID=%04X\r\n", LL_DBGMCU_GetRevisionID() ); + + if ((TxLongPacketGetNextChunkCb==NULL)|| + (payload_size> (1<<(8*RFWPacket.Init.PayloadLengthFieldSize))-1) ||/*check that size fits inside the packetLengthField*/ + (RFWPacket.Init.Enable==0) ||/* Can only be used when after RadioSetTxGenericConfig*/ + (LL_DBGMCU_GetRevisionID() < 0x1003 ) ) /* Only available from stm32wl revision Y*/ + { + status= -1; + } + else + { + /*chunk buffer pointer fed by the application*/ + uint8_t* app_chunk_buffer_ptr=NULL; + /*size of the chunk to be sent*/ + uint8_t chunk_size; + uint8_t crc_size; + /*timeout for next chunk*/ + uint32_t chunk_timeout; + /*Records call back*/ + RFWPacket.TxLongPacketGetNextChunkCb=TxLongPacketGetNextChunkCb; + + /* Radio IRQ is set to DIO1 by default */ + SUBGRF_SetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + /* ST_WORKAROUND_BEGIN : Set the debug pin and update the radio switch */ + /* Set DBG pin */ + DBG_GPIO_RADIO_TX(SET); + /* Set RF switch */ + SUBGRF_SetSwitch(RFWPacket.AntSwitchPaSelect, RFSWITCH_TX); + /* ST_WORKAROUND_END */ + + switch(RFWPacket.Init.Modem) + { + case MODEM_FSK: + { + if (RFWPacket.Init.Enable==1) + { + /*crc will be calculated on the fly along with packet chunk transmission*/ + uint8_t crc_result[2]; + /*init radio buffer offset*/ + RFWPacket.RadioBufferOffset=0; + /*long packet mode enable*/ + RFWPacket.LongPacketModeEnable=1; + /*Remaining bytes to transmit*/ + RFWPacket.LongPacketRemainingBytes=total_size; + /*Records total payload bytes to transmit*/ + RFWPacket.PayloadLength=total_size; + if (total_size> RADIO_BUF_SIZE) + { + /*cut in chunk*/ + if (total_size>8); + ChunkBuffer[1]=(uint8_t) ((payload_size)&0xFF); + } + /* Get Tx chunk from app*/ + TxLongPacketGetNextChunkCb(&app_chunk_buffer_ptr, chunk_size); + + /* Copy first chunk in ChunkBuffer Buffer*/ + RADIO_MEMCPY8(&ChunkBuffer[RFWPacket.Init.PayloadLengthFieldSize], app_chunk_buffer_ptr, chunk_size); + + if (RFWPacket.Init.CrcEnable== 1) + { + /* Set the state of the Crc to crc_seed*/ + RFW_CrcSetState(&RFWPacket); + /* Run the crc calculation on payload length and payload*/ + RFW_CrcRun(&RFWPacket, ChunkBuffer, RFWPacket.Init.PayloadLengthFieldSize+ chunk_size, crc_result); + /* Append the crc result after the payload if total_size<= RADIO_BUF_SIZE*/ + RADIO_MEMCPY8(&ChunkBuffer[RFWPacket.Init.PayloadLengthFieldSize+ chunk_size], crc_result, crc_size); + } + /* Init whitening at beginning of the packet*/ + RFW_WhiteSetState(&RFWPacket); + /* Run the whitening calculation on payload length, payload and crc if crc fits inside 1st chunk*/ + RFW_WhiteRun(&RFWPacket, &ChunkBuffer[0],RFWPacket.Init.PayloadLengthFieldSize+ chunk_size+ crc_size); + /* Configure the Transmitter to send all*/ + /* Init radio buffer */ + SUBGRF_WriteRegister(SUBGHZ_RTXPLDLEN,RFWPacket.Init.PayloadLengthFieldSize+ chunk_size+ crc_size); + SUBGRF_WriteRegister(SUBGHZ_TX_ADR_PTR,0); + /* Send*/ + SUBGRF_SendPayload( ChunkBuffer, RFWPacket.Init.PayloadLengthFieldSize+ chunk_size+ crc_size, 0 ); + if (total_size> RADIO_BUF_SIZE) + { + /*in case total size is greater than RADIO_BUF_SIZE, need to program a timer to get next chunk*/ + //RFWPacket.LongPacketRemainingBytes-= RFWPacket.Init.PayloadLengthFieldSize+ chunk_size+ crc_size; + /*Initialize Timer to get new chunk and update radio ptr*/ + chunk_timeout = ( LONGPACKET_CHUNK_LENGTH_BYTES* 8 * 1000)/RFWPacket.BitRate; + RFW_MW_LOG( TS_ON, VLEVEL_M, "Timeout=%d,\r\n", chunk_timeout); + TimerInit( &RFWPacket.Timer, RFW_TransmitLongPacket_NewTxChunkTimerEvent ); + TimerSetValue( &RFWPacket.Timer, chunk_timeout ); + TimerStart( &RFWPacket.Timer); + /*Write bit infinite_sequence = 1, required for long packet*/ + uint8_t reg = SUBGRF_ReadRegister(SUBGHZ_PKTCTL1A); + SUBGRF_WriteRegister(SUBGHZ_PKTCTL1A, reg | 0x02); + + TimerSetValue( RFWPacket.RxTimeoutTimer, timeout ); + TimerStart( RFWPacket.RxTimeoutTimer); + } + } + else + { + /* error*/ + status= -1; + } + break; + } + case MODEM_LORA: + { + /* not supported by the radio Ip*/ + status= -2; + break; + } + case MODEM_BPSK: + { + /* not supported by the FW*/ + status= -2; + break; + } + case MODEM_SIGFOX_TX: + { + /* not supported by the FW*/ + status= -2; + break; + } + default: + break; + } + } +#else + status= -1; +#endif + return status; +} + +int32_t RFW_ReceiveLongPacket( uint8_t boosted_mode, uint32_t timeout, void (*RxLongPacketStoreChunkCb) (uint8_t* buffer, uint8_t chunk_size) ) +{ + int32_t status=0; +#if (RFW_LONGPACKET_ENABLE ==1 ) + if ((RxLongPacketStoreChunkCb==NULL) || + (RFWPacket.Init.Enable==0)) /* Can only be used when after RadioSetRxGenericConfig*/ + { + status= -1; + } + else + { + /*Records call back*/ + RFWPacket.RxLongPacketStoreChunkCb=RxLongPacketStoreChunkCb; + SUBGRF_SetDioIrqParams( IRQ_SYNCWORD_VALID | IRQ_RX_TX_TIMEOUT, + IRQ_SYNCWORD_VALID | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + SUBGRF_SetSwitch(RFWPacket.AntSwitchPaSelect, RFSWITCH_RX); + /*init radio buffer offset*/ + RFWPacket.RadioBufferOffset=0; + /* Init whitening at beginning of the packet*/ + RFW_WhiteSetState(&RFWPacket); + /* Set the state of the Crc to crc_seed*/ + RFW_CrcSetState(&RFWPacket); + /* Init radio buffer */ + SUBGRF_WriteRegister(SUBGHZ_RTXPLDLEN,255); + SUBGRF_WriteRegister(SUBGHZ_RX_ADR_PTR,0); + /*enable long packet*/ + RFWPacket.LongPacketModeEnable=1; + + if( timeout != 0 ) + { + TimerSetValue( RFWPacket.RxTimeoutTimer, timeout ); + TimerStart( RFWPacket.RxTimeoutTimer ); + } + DBG_GPIO_RADIO_RX(SET); + if (boosted_mode ==1) + { + SUBGRF_SetRxBoosted( 0xFFFFFF ); // Rx Continuous + } + else + { + SUBGRF_SetRx( 0xFFFFFF ); // Rx Continuous + } + } +#else + status= -1; +#endif + return status; +} + +int32_t RFW_Init( ConfigGeneric_t* config, RadioEvents_t* RadioEvents, TimerEvent_t* TimeoutTimerEvent) +{ +#if (RFW_ENABLE ==1 ) + RADIO_FSK_PacketLengthModes_t HeaderType; + uint32_t RxMaxPayloadLength= 0; + RADIO_FSK_CrcTypes_t CrcLength; + uint16_t whiteSeed; + uint16_t CrcPolynomial; + uint16_t CrcSeed; + if (config->rtx ==CONFIG_TX) + { + HeaderType= config->TxConfig->fsk.HeaderType; + CrcLength= config->TxConfig->fsk.CrcLength; + whiteSeed= config->TxConfig->fsk.whiteSeed; + CrcPolynomial= config->TxConfig->fsk.CrcPolynomial; + CrcSeed= config->TxConfig->fsk.CrcSeed; + RFWPacket.BitRate= config->TxConfig->fsk.BitRate; + RFWPacket.TxTimeoutTimer= TimeoutTimerEvent; + } + else + { + HeaderType= config->RxConfig->fsk.LengthMode; + CrcLength= config->RxConfig->fsk.CrcLength; + RxMaxPayloadLength = config->RxConfig->fsk.MaxPayloadLength; + whiteSeed= config->RxConfig->fsk.whiteSeed; + CrcPolynomial= config->RxConfig->fsk.CrcPolynomial; + CrcSeed= config->RxConfig->fsk.CrcSeed; + RFWPacket.BitRate= config->RxConfig->fsk.BitRate; + RFWPacket.RxTimeoutTimer= TimeoutTimerEvent; + } + if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) + { + RFWPacket.Init.RadioEvents=RadioEvents; + } + else + { + return -1; + } + if (HeaderType==RADIO_FSK_PACKET_2BYTES_LENGTH) + { +#if (RFW_LONGPACKET_ENABLE ==1 ) + RFWPacket.Init.PayloadLengthFieldSize= 2; +#else + return -1; +#endif + } + else + { + RFWPacket.Init.PayloadLengthFieldSize= 1; + } + /*record, used to reject packet in length decoded at sync time out greater than LongPacketMaxRxLength*/ + RFWPacket.Init.LongPacketMaxRxLength= RxMaxPayloadLength; + if (CrcLength== RADIO_FSK_CRC_OFF) + { + RFWPacket.Init.CrcEnable =0; + RFWPacket.Init.CrcFieldSize= 0; + } + else + { + RFWPacket.Init.CrcEnable =1; + RFWPacket.Init.CrcFieldSize= 2; + } + /*Macro can be used to init interrupt behaviour*/ + RFW_IT_INIT(); + /*Initialise whitening Seed*/ + RFW_WhiteInitState(&RFWPacket.Init, whiteSeed); + /*Initialise Crc Seed*/ + RFW_CrcInitState(&RFWPacket.Init, CrcPolynomial, CrcSeed, CrcLength); + /*Enable the RFWPacket decoding*/ + RFWPacket.Init.Enable=1; + /* Initialize Timer for end of fixed packet, started at sync*/ + TimerInit( &RFWPacket.Timer, RFW_GetPayloadTimerEvent ); + return 0; +#else + return -1; +#endif +} + +void RFW_DeInit( void) +{ +#if (RFW_ENABLE ==1 ) + RFWPacket.Init.Enable=0; /*Disable the RFWPacket decoding*/ +#endif +} + +uint8_t RFW_Is_Init( void) +{ +#if (RFW_ENABLE ==1 ) + return RFWPacket.Init.Enable; +#else + return 0; +#endif +} + +uint8_t RFW_Is_LongPacketModeEnabled( void) +{ +#if (RFW_ENABLE ==1 ) + return RFWPacket.LongPacketModeEnable; +#else + return 0; +#endif +} + +void RFW_SetAntSwitch( uint8_t AntSwitch) +{ +#if (RFW_ENABLE ==1 ) + RFWPacket.AntSwitchPaSelect=AntSwitch; +#endif +} + +int32_t RFW_TransmitInit(uint8_t* inOutBuffer, uint8_t size, uint8_t* outSize) +{ + int32_t status=-1; +#if (RFW_ENABLE ==1 ) + uint8_t crc_result[2]; + if (size+RFWPacket.Init.PayloadLengthFieldSize+ RFWPacket.Init.CrcFieldSize> RADIO_BUF_SIZE) + { + RFW_MW_LOG( TS_ON, VLEVEL_M, "RadioSend Oversize\r\n"); + status= -1; + } + else + { + /* Copy tx buffer in payload*/ + RADIO_MEMCPY8(&ChunkBuffer[RFWPacket.Init.PayloadLengthFieldSize], inOutBuffer, size); + /* Calculate the crc on */ + /* Payload Size without the packet length field nor the CRC */ + /* Prepend payload size before Payload*/ + if (RFWPacket.Init.PayloadLengthFieldSize==1) + { + ChunkBuffer[0]=size; + } + else + { + ChunkBuffer[0]=0; + ChunkBuffer[1]=size; + } + if (RFWPacket.Init.CrcEnable== 1) + { + /* Set the state of the Crc to crc_seed*/ + RFW_CrcSetState(&RFWPacket); + /*Run the crc calculation on payload length and payload*/ + RFW_CrcRun(&RFWPacket, &ChunkBuffer[0],size+ RFWPacket.Init.PayloadLengthFieldSize, crc_result); + /*append the crc result afater the payload*/ + RADIO_MEMCPY8(&ChunkBuffer[size+ RFWPacket.Init.PayloadLengthFieldSize], crc_result, RFWPacket.Init.CrcFieldSize); + } + /*init whitening at beginning of the packet*/ + RFW_WhiteSetState(&RFWPacket); + /*Run the whitening calculation on payload length, payload and crc*/ + RFW_WhiteRun(&RFWPacket, &ChunkBuffer[0],size+ RFWPacket.Init.PayloadLengthFieldSize+ RFWPacket.Init.CrcFieldSize); + /*Configure the Transmitter to send all*/ + *outSize=(uint8_t) size+ RFWPacket.Init.PayloadLengthFieldSize+ RFWPacket.Init.CrcFieldSize; + /*copy result*/ + RADIO_MEMCPY8(inOutBuffer, ChunkBuffer, *outSize); + + RFWPacket.LongPacketModeEnable=0; + + status= 0; + } +#endif + return status; +} + +int32_t RFW_ReceiveInit( void ) +{ +#if (RFW_ENABLE ==1 ) + /* Radio IRQ is set to DIO1 by default */ + SUBGRF_SetDioIrqParams( IRQ_RADIO_ALL&(~IRQ_RX_DONE), //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_ALL&(~IRQ_RX_DONE), //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); +/*init whitening at beginning of the packet*/ + RFW_WhiteSetState(&RFWPacket); +/* Set the state of the Crc to crc_seed*/ + RFW_CrcSetState(&RFWPacket); + + RFWPacket.RxPayloadOffset=0; + + RFWPacket.LongPacketModeEnable=0; + return 0; +#else + return -1; +#endif +} + +void RFW_DeInit_TxLongPacket(void) +{ +#if (RFW_LONGPACKET_ENABLE ==1 ) + /*long packet WA*/ + uint8_t reg = SUBGRF_ReadRegister(SUBGHZ_PKTCTL1A); + SUBGRF_WriteRegister(SUBGHZ_PKTCTL1A, reg & ~0x02);//clear infinite_sequence bit + SUBGRF_WriteRegister(SUBGHZ_RTXPLDLEN, 0xFF); //RxTxPldLen: reset to 0xFF +#endif +} + +void RFW_ReceivePayload( void ) +{ +#if (RFW_ENABLE ==1 ) + uint16_t PayloadLength= 0; + if (RFW_GetPacketLength(&PayloadLength)==0) + { + uint32_t timeout; + uint32_t packet_length= PayloadLength+RFWPacket.Init.CrcFieldSize; + /*record payload length*/ + RFWPacket.PayloadLength= PayloadLength; + /*record remaining payload length*/ + RFWPacket.LongPacketRemainingBytes = (uint16_t) packet_length; + /*record rx buffer offset*/ + RFWPacket.RadioBufferOffset = RFWPacket.Init.PayloadLengthFieldSize; + /*if decoded PayloadLength is longer than LongPacketMaxRxLength, reject packet*/ + if (PayloadLength>RFWPacket.Init.LongPacketMaxRxLength) + { + SUBGRF_SetStandby( STDBY_RC ); + RFWPacket.Init.RadioEvents->RxError( ); + return; + } + if (packet_lengthRxTimeout( ); + } +#endif +} + +void RFW_SetRadioModem(RadioModems_t Modem) +{ +#if (RFW_ENABLE ==1 ) + RFWPacket.Init.Modem= Modem; +#endif +} + +/* Private Functions Definition -----------------------------------------------*/ +#if (RFW_LONGPACKET_ENABLE ==1 ) +static void RFW_TransmitLongPacket_NewTxChunkTimerEvent( void * param ) +{ + RFW_TRANSMIT_LONGPACKET_TX_CHUNK_PROCESS(); +} + +static void RFW_TransmitLongPacket_TxChunkProcess( void ) +{ + uint8_t* app_chunk_buffer_ptr=NULL; + uint8_t chunk_size=0; + uint8_t crc_result[2]={0}; + uint8_t crc_size; + uint32_t timeout;/*timeout for next chunk*/ + /*records how much has been sent*/ + uint8_t read_ptr= SUBGRF_ReadRegister(SUBGHZ_TX_ADR_PTR); /*radio has transmitted up to read_ptr*/ + uint8_t write_ptr= SUBGRF_ReadRegister(SUBGHZ_RTXPLDLEN); /*from read_ptr to write_ptr still to be transmitted*/ + /*calculates how much bytes were sent since previous radio loading*/ + uint8_t bytes_sent =read_ptr-RFWPacket.RadioBufferOffset; + /*bytes already loaded in the radio to send*/ + uint8_t bytes_loaded= write_ptr-read_ptr; + + /* Update offset tx, intentional wrap around*/ + RFWPacket.RadioBufferOffset+= bytes_sent; + /*record payload remaining bytes to send*/ + RFWPacket.LongPacketRemainingBytes-= bytes_sent; + RFW_MW_LOG( TS_ON, VLEVEL_M, "read_ptr=%d, write_ptr=%d, bytes_sent=%d, bytes_loaded=%d,remaining to send=%d\r\n", + read_ptr, write_ptr,bytes_sent, bytes_loaded,RFWPacket.LongPacketRemainingBytes); + if ( RFWPacket.LongPacketRemainingBytes> 256) + { + /*get next chunk */ + /*make sure that at least full CrcFieldSize will be loaded for the last chunk*/ + if ( RFWPacket.LongPacketRemainingBytes>256+RFWPacket.Init.CrcFieldSize) + { + chunk_size = bytes_sent; + } + else + { + chunk_size = bytes_sent-RFWPacket.Init.CrcFieldSize; + } + /*no crc since it is not the last chunk*/ + crc_size= 0; + /*calculate timeout for next chunk*/ + timeout = DIVR( chunk_size* 8 * 1000 , RFWPacket.BitRate); + + TimerSetValue( &RFWPacket.Timer, timeout ); + TimerStart( &RFWPacket.Timer); + } + else + { + /*last chunk to send*/ + + if (RFWPacket.LongPacketRemainingBytes>bytes_loaded) + { + chunk_size = RFWPacket.LongPacketRemainingBytes-bytes_loaded; + } + else/* nothing to load anymore*/ + { + chunk_size =RFWPacket.Init.CrcFieldSize; + } + /* crc, since it is the last chunk*/ + crc_size= RFWPacket.Init.CrcFieldSize; + /*no more bytes to send*/ + RFWPacket.LongPacketRemainingBytes= 0; + /*no need to program another timer, Tx done will complete the Tx process*/ + } + /*get new chunk from the app*/ + RFWPacket.TxLongPacketGetNextChunkCb( &app_chunk_buffer_ptr, chunk_size-crc_size); + /* Copy app_chunk_buffer_ptr in ChunkBuffer Buffer*/ + RADIO_MEMCPY8(ChunkBuffer, app_chunk_buffer_ptr, chunk_size-crc_size); + if (RFWPacket.Init.CrcEnable== 1) + { + /* Run the crc calculation on payload length and payload*/ + RFW_CrcRun(&RFWPacket, ChunkBuffer, chunk_size-crc_size, crc_result); + /* Append the crc result after the payload (if last chunk)*/ + RADIO_MEMCPY8(&ChunkBuffer[chunk_size-crc_size], crc_result, crc_size); + } + /* Run the whitening calculation on payload length, payload and crc*/ + RFW_WhiteRun(&RFWPacket, ChunkBuffer, chunk_size); + /*write next chunk*/ + SUBGRF_WriteBuffer( write_ptr, ChunkBuffer, chunk_size ); + + /*update end ptr*/ + SUBGRF_WriteRegister(SUBGHZ_RTXPLDLEN, (uint8_t)(chunk_size + write_ptr)); + + RFW_MW_LOG( TS_ON, VLEVEL_M, "next chunk size=%d, new write ptr=%d\n\r",chunk_size+ crc_size, (uint8_t)(chunk_size+ crc_size + write_ptr)); +} +#endif + +#if (RFW_ENABLE ==1 ) +static void RFW_WhiteInitState(RFwInit_t* Init, uint16_t WhiteSeed) +{ + Init->WhiteSeed= WhiteSeed; +} + +static void RFW_WhiteSetState(RadioFw_t* RFWPacket) +{ + RFWPacket->WhiteLfsrState= RFWPacket->Init.WhiteSeed; +} + +static void RFW_CrcInitState(RFwInit_t* Init, const uint16_t CrcPolynomial, const uint16_t CrcSeed, const RADIO_FSK_CrcTypes_t CrcType) +{ + Init->CrcPolynomial= CrcPolynomial; + Init->CrcSeed= CrcSeed; + Init->CrcType= CrcType; +} + +static void RFW_CrcSetState(RadioFw_t* RFWPacket) +{ + RFWPacket->CrcLfsrState= RFWPacket->Init.CrcSeed; +} + +static void RFW_WhiteRun(RadioFw_t* RFWPacket, uint8_t* Payload, uint32_t Size) +{ + /*run the whitening algo on Size bytes*/ + uint16_t ibmwhite_state= RFWPacket->WhiteLfsrState; + for(int i=0;i>5)&0x1)^((ibmwhite_state>>0)&0x1); + ibmwhite_state= ((msb<<8) | (ibmwhite_state>>1) ); + } + } + RFWPacket->WhiteLfsrState=ibmwhite_state; +} + +static int32_t RFW_CrcRun(RadioFw_t* const RFWPacket, const uint8_t* Payload, const uint32_t Size, uint8_t CrcResult[2]) +{ + int32_t status=0; + int32_t i = 0; + uint16_t polynomial = RFWPacket->Init.CrcPolynomial; + /* Restore state from previous chunk*/ + uint16_t crc = RFWPacket->CrcLfsrState; + for( i = 0; i < Size; i++ ) + { + crc = RFW_CrcRun1Byte( crc, Payload[i], polynomial ); + } + /*Save state for next chunk*/ + RFWPacket->CrcLfsrState=crc; + + if( RFWPacket->Init.CrcType == RADIO_FSK_CRC_2_BYTES_IBM ) + { + CrcResult[1]=crc&0xFF; + CrcResult[0]=crc>>8; + } + else + { + crc= ~crc ; + CrcResult[1]=crc&0xFF; + CrcResult[0]=crc>>8; + } + return status; +} + +uint16_t RFW_CrcRun1Byte( uint16_t Crc, uint8_t DataByte, uint16_t Polynomial) +{ + uint8_t i; + for( i = 0; i < 8; i++ ) + { + if( ( ( ( Crc & 0x8000 ) >> 8 ) ^ ( DataByte & 0x80 ) ) != 0 ) + { + Crc <<= 1; + Crc ^= Polynomial; + } + else + { + Crc <<= 1; + } + DataByte <<= 1; + } + return Crc; +} + +static int32_t RFW_PollRxBytes(uint32_t bytes) +{ + uint32_t now = TimerGetCurrentTime( ); + uint8_t reg_buff_ptr_ref= SUBGRF_ReadRegister(SUBGHZ_RX_ADR_PTR); + uint8_t reg_buff_ptr=reg_buff_ptr_ref; + uint32_t timeout = DIVC( bytes* 8 * 1000 , RFWPacket.BitRate); + // Wait that packet length is received + while( (reg_buff_ptr-reg_buff_ptr_ref) < bytes) + { + /*reading rx address pointer*/ + reg_buff_ptr=SUBGRF_ReadRegister(SUBGHZ_RX_ADR_PTR); + if( TimerGetElapsedTime( now ) > timeout) + { + /*timeout*/ + return -1; + } + } + return 0; +} + +static int32_t RFW_GetPacketLength(uint16_t* PayloadLength) +{ + if ( 0UL!= RFW_PollRxBytes(RFWPacket.Init.PayloadLengthFieldSize)) + { + return -1; + } + /* Get buffer from Radio*/ + SUBGRF_ReadBuffer( 0, ChunkBuffer, RFWPacket.Init.PayloadLengthFieldSize ); + /* De-whiten packet length*/ + RFW_WhiteRun(&RFWPacket, ChunkBuffer ,RFWPacket.Init.PayloadLengthFieldSize); + /*do crc 1st calculation packetLengthField and store intermediate result */ + if (RFWPacket.Init.CrcEnable== 1) + { + /*run Crc algo on payloadLengthField*/ + uint8_t crc_dummy[2]; + RFW_CrcRun(&RFWPacket, ChunkBuffer, RFWPacket.Init.PayloadLengthFieldSize, crc_dummy); + } + if (RFWPacket.Init.PayloadLengthFieldSize==1) + { + *PayloadLength= (uint16_t) ChunkBuffer[0]; + } + else + { + /*packet length is 2 bytes*/ + *PayloadLength= (((uint16_t) ChunkBuffer[0])<<8) |ChunkBuffer[1]; + /*disable preamble detector*/ + //uint8_t reg= SUBGRF_ReadRegister( SUBGHZ_PKTCTL1 ); + //SUBGRF_WriteRegister(SUBGHZ_PKTCTL1, reg&(~0x02)); + } + RFW_MW_LOG( TS_ON, VLEVEL_M, "PayloadLength=%d,\r\n", *PayloadLength); + return 0; +} + +static void RFW_GetPayloadTimerEvent( void * context) +{ + RFW_GET_PAYLOAD_PROCESS(); +} + +static void RFW_GetPayloadProcess( void ) +{ + /*long packet mode*/ + uint8_t read_ptr= SUBGRF_ReadRegister(SUBGHZ_RX_ADR_PTR); + uint8_t size=read_ptr-RFWPacket.RadioBufferOffset; + uint32_t Timeout; + /*check remaining size*/ + if (RFWPacket.LongPacketRemainingBytes>size) + { + /* update LongPacketRemainingBytes*/ + RFWPacket.LongPacketRemainingBytes-=size; + /*intermediate chunk*/ + RFW_MW_LOG( TS_ON, VLEVEL_M, "RxTxPldLen=0x%02X,\r\n",SUBGRF_ReadRegister(SUBGHZ_RTXPLDLEN)); + RFW_MW_LOG( TS_ON, VLEVEL_M, "RxAddrPtr=0x%02X,\r\n",read_ptr); + RFW_MW_LOG( TS_ON, VLEVEL_M, "offset= %d, size=%d, remaining=%d,\r\n",RFWPacket.RadioBufferOffset, size, RFWPacket.LongPacketRemainingBytes); + /*update pld length so that not reached*/ + SUBGRF_WriteRegister(SUBGHZ_RTXPLDLEN, read_ptr-1); + /* read data from radio*/ + SUBGRF_ReadBuffer( RFWPacket.RadioBufferOffset, ChunkBuffer, size ); + /* update buffer Offset, with intentional wrap around*/ + RFWPacket.RadioBufferOffset+=size; + /*Run the de-whitening on current chunk*/ + RFW_WhiteRun(&RFWPacket, ChunkBuffer, size); + if (RFWPacket.Init.CrcEnable== 1) + { + /*run Crc algo on partial chunk*/ + uint8_t crc_dummy[2]; + RFW_CrcRun(&RFWPacket, ChunkBuffer, size, crc_dummy); + } + + if (RFWPacket.LongPacketModeEnable ==1) + { + /*report rx data chunk to application*/ + RFWPacket.RxLongPacketStoreChunkCb( ChunkBuffer, size); + } + else + { + if (RFWPacket.RxPayloadOffset+=sizeRxError( ); + return; + } + } + /*calculate next timer timeout*/ + if (RFWPacket.LongPacketRemainingBytesRxError( ); + return; + } + } + TimerStop( RFWPacket.RxTimeoutTimer ); + /* CRC check*/ + RFW_MW_LOG( TS_ON, VLEVEL_M, "crc_result= 0x%02X%02X, crc_payload=0x%02X%02X\r\n",crc_result[0],crc_result[1],ChunkBuffer[Length-2],ChunkBuffer[Length-1]); + if (((crc_result[0]==ChunkBuffer[Length-2]) && + (crc_result[1]==ChunkBuffer[Length-1])) || + (RFWPacket.Init.CrcEnable== 0)) + { + /*read Rssi sampled at Sync*/ + uint8_t rssi_sync = SUBGRF_ReadRegister(0x06CA); + /* Get Carrier Frequency Offset*/ + int32_t cfo; + SUBGRF_GetCFO(RFWPacket.BitRate, &cfo); + /*ChunkBuffer[1] to remove packet Length*/ + RFWPacket.Init.RadioEvents->RxDone( RxBuffer, + RFWPacket.RxPayloadOffset, + -(rssi_sync>>1), + (int8_t) DIVR(cfo,1000)); + } + else + { + /*report CRC error*/ + RFWPacket.Init.RadioEvents->RxError( ); + } + DBG_GPIO_RADIO_RX(RST); +} +#endif +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_fw.h b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_fw.h new file mode 100644 index 00000000..6057fae8 --- /dev/null +++ b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/radio_fw.h @@ -0,0 +1,145 @@ +/** + ****************************************************************************** + * @file radio_fw.h + * @author MCD Application Team + * @brief Extends radio capabilities (whitening, long packet) + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __RADIO_FW_H__ +#define __RADIO_FW_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + +/*reserved for SubGHz_Phy internal MW communication*/ +typedef enum +{ + CONFIG_RX = 0, + CONFIG_TX, +}ConfigGenericRTx_t; + +typedef struct{ + TxConfigGeneric_t* TxConfig; + RxConfigGeneric_t* RxConfig; + ConfigGenericRTx_t rtx; +} ConfigGeneric_t; + +/* Exported constants --------------------------------------------------------*/ +/* External variables --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions prototypes ---------------------------------------------*/ + +/*! + * @brief Initialise the RFW module and enables custom whithing, optionally long packet feature + * + * @param [IN] config rx or tx config from the application + * @param [IN] RadioEvents from the radio + * @return 0 when no parameters error, -1 otherwise + */ +int32_t RFW_Init( ConfigGeneric_t* config, RadioEvents_t* RadioEvents, TimerEvent_t* TimeoutTimerEvent); + +/*! + * @brief Return whether the RFW module is enabled + * + * @return 0 when not initialised, -1 otherwise + */ +uint8_t RFW_Is_Init( void); + +/*! + * @brief Return whether the RFW module long packet is enabled + * + * @return 0 when not initialised, -1 otherwise + */ +uint8_t RFW_Is_LongPacketModeEnabled( void); + +/*! + * @brief Return whether the RFW module long packet is enabled + * + * @param [IN] RadioModems_t set in the radio + */ +void RFW_SetRadioModem(RadioModems_t Modem); + +/*! + * @brief DeInitialise the RFW module and enable custom whithing and optionally long packet feature + * + */ +void RFW_DeInit( void); + +/*! + * @brief DeInitialise the TxLongPacket + * + */ +void RFW_DeInit_TxLongPacket(void); + +/*! + * @brief Set antenna switch output to be used in Tx + * + * @param [IN] AntSwitch RFO_LP or FRO_HP + * + */ +void RFW_SetAntSwitch( uint8_t AntSwitch); + +/*! + * @brief Initialise reception for IBM whitening case + * + */ +int32_t RFW_ReceiveInit( void ); + +/*! + * @brief Initialise transmission for IBM whitening case + * + */ +int32_t RFW_TransmitInit(uint8_t* inOutBuffer, uint8_t size, uint8_t* outSize); + +/*! + * @brief Starts receiving payload. Called at Rx Sync IRQ + * + */ +void RFW_ReceivePayload(void ); + +/*! + * @brief Starts transmitting long Packet, note packet length may be on 1 bytes depending on config + * + * @param [IN] payload_size total payload size to be sent + * @param [IN] TxLongPacketGetNextChunkCb callback to be implemented on user side to feed partial chunk + * buffer: source buffer allocated by the app + * size: size in bytes to feed. User to implement the offset based on previous chunk request + * @return 0 when no parameters error, -1 otherwise + */ +int32_t RFW_TransmitLongPacket( uint16_t payload_size, uint32_t timeout, void (*TxLongPacketGetNextChunkCb) (uint8_t** buffer, uint8_t buffer_size) ); + +/*! + * @brief Starts receiving long Packet, packet maybe short + * + * @param [IN] boosted_mode boosted_mode: 0 normal Rx, 1:improved sensitivity + * @param [IN] timeout Reception timeout [ms] + * @param [IN] RxLongStorePacketChunkCb callback to be implemented on user side to record partial chunk in the application + * buffer: source buffer allocated in the radio driver + * size: size in bytes to record + * @return 0 when no parameters error, -1 otherwise + */ +int32_t RFW_ReceiveLongPacket( uint8_t boosted_mode, uint32_t timeout, void (*RxLongStorePacketChunkCb) (uint8_t* buffer, uint8_t chunk_size) ); + +#ifdef __cplusplus +} +#endif + +#endif /*__RADIO_FW_H__*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/subghz_phy_version.h b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/subghz_phy_version.h index 4deb396d..d4c21628 100644 --- a/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/subghz_phy_version.h +++ b/Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver/subghz_phy_version.h @@ -34,9 +34,9 @@ 0x76 SX1276 */ #define __SUBGHZ_PHY_TYPE (0x01U) /*!< [31:24] main version */ -#define __SUBGHZ_PHY_VERSION_MAIN (0x00U) /*!< [23:16] main version */ -#define __SUBGHZ_PHY_VERSION_SUB1 (0x06U) /*!< [15:8] sub1 version */ -#define __SUBGHZ_PHY_VERSION_SUB2 (0x01U) /*!< [7:0] sub2 version */ +#define __SUBGHZ_PHY_VERSION_MAIN (0x01U) /*!< [23:16] main version */ +#define __SUBGHZ_PHY_VERSION_SUB1 (0x01U) /*!< [15:8] sub1 version */ +#define __SUBGHZ_PHY_VERSION_SUB2 (0x00U) /*!< [7:0] sub2 version */ #define __SUBGHZ_PHY_VERSION ((__SUBGHZ_PHY_VERSION_MAIN << 24) \ |(__SUBGHZ_PHY_VERSION_SUB1 << 16) \ |(__SUBGHZ_PHY_VERSION_SUB2 << 8 ) \ diff --git a/Middlewares/Third_Party/mbed-crypto/programs/psa/key_ladder_demo.sh b/Middlewares/Third_Party/mbed-crypto/programs/psa/key_ladder_demo.sh deleted file mode 100644 index 2cec945f..00000000 --- a/Middlewares/Third_Party/mbed-crypto/programs/psa/key_ladder_demo.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -set -e -u - -program="${0%/*}"/key_ladder_demo -files_to_clean= - -run () { - echo - echo "# $1" - shift - echo "+ $*" - "$@" -} - -if [ -e master.key ]; then - echo "# Reusing the existing master.key file." -else - files_to_clean="$files_to_clean master.key" - run "Generate a master key." \ - "$program" generate master=master.key -fi - -files_to_clean="$files_to_clean input.txt hello_world.wrap" -echo "Here is some input. See it wrapped." >input.txt -run "Derive a key and wrap some data with it." \ - "$program" wrap master=master.key label=hello label=world \ - input=input.txt output=hello_world.wrap - -files_to_clean="$files_to_clean hello_world.txt" -run "Derive the same key again and unwrap the data." \ - "$program" unwrap master=master.key label=hello label=world \ - input=hello_world.wrap output=hello_world.txt -run "Compare the unwrapped data with the original input." \ - cmp input.txt hello_world.txt - -files_to_clean="$files_to_clean hellow_orld.txt" -! run "Derive a different key and attempt to unwrap the data. This must fail." \ - "$program" unwrap master=master.key input=hello_world.wrap output=hellow_orld.txt label=hellow label=orld - -files_to_clean="$files_to_clean hello.key" -run "Save the first step of the key ladder, then load it as a master key and construct the rest of the ladder." \ - "$program" save master=master.key label=hello \ - input=hello_world.wrap output=hello.key -run "Check that we get the same key by unwrapping data made by the other key." \ - "$program" unwrap master=hello.key label=world \ - input=hello_world.wrap output=hello_world.txt - -# Cleanup -rm -f $files_to_clean diff --git a/Middlewares/Third_Party/mbed-crypto/scripts/apidoc_full.sh b/Middlewares/Third_Party/mbed-crypto/scripts/apidoc_full.sh deleted file mode 100644 index bebab103..00000000 --- a/Middlewares/Third_Party/mbed-crypto/scripts/apidoc_full.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# Generate doxygen documentation with a full config.h (this ensures that every -# available flag is documented, and avoids warnings about documentation -# without a corresponding #define). -# -# /!\ This must not be a Makefile target, as it would create a race condition -# when multiple targets are invoked in the same parallel build. - -set -eu - -CONFIG_H='include/mbedtls/config.h' - -if [ -r $CONFIG_H ]; then :; else - echo "$CONFIG_H not found" >&2 - exit 1 -fi - -CONFIG_BAK=${CONFIG_H}.bak -cp -p $CONFIG_H $CONFIG_BAK - -scripts/config.pl realfull -make apidoc - -mv $CONFIG_BAK $CONFIG_H diff --git a/Middlewares/Third_Party/mbed-crypto/scripts/bump_version.sh b/Middlewares/Third_Party/mbed-crypto/scripts/bump_version.sh deleted file mode 100644 index d76e313c..00000000 --- a/Middlewares/Third_Party/mbed-crypto/scripts/bump_version.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/bash -# -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2012-2016, ARM Limited, All Rights Reserved -# -# Purpose -# -# Sets the version numbers in the source code to those given. -# -# Usage: bump_version.sh [ --version ] [ --so-crypto ] -# [ -v | --verbose ] [ -h | --help ] -# - -VERSION="" -SOVERSION="" - -# Parse arguments -# -until [ -z "$1" ] -do - case "$1" in - --version) - # Version to use - shift - VERSION=$1 - ;; - --so-crypto) - shift - SO_CRYPTO=$1 - ;; - -v|--verbose) - # Be verbose - VERBOSE="1" - ;; - -h|--help) - # print help - echo "Usage: $0" - echo -e " -h|--help\t\tPrint this help." - echo -e " --version \tVersion to bump to." - echo -e " --so-crypto \tSO version to bump libmbedcrypto to." - echo -e " -v|--verbose\t\tVerbose." - exit 1 - ;; - *) - # print error - echo "Unknown argument: '$1'" - exit 1 - ;; - esac - shift -done - -if [ "X" = "X$VERSION" ]; -then - echo "No version specified. Unable to continue." - exit 1 -fi - -[ $VERBOSE ] && echo "Bumping VERSION in library/CMakeLists.txt" -sed -e "s/ VERSION [0-9.]\{1,\}/ VERSION $VERSION/g" < library/CMakeLists.txt > tmp -mv tmp library/CMakeLists.txt - -if [ "X" != "X$SO_CRYPTO" ]; -then - [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedcrypto in library/CMakeLists.txt" - sed -e "/mbedcrypto/ s/ SOVERSION [0-9]\{1,\}/ SOVERSION $SO_CRYPTO/g" < library/CMakeLists.txt > tmp - mv tmp library/CMakeLists.txt - - [ $VERBOSE ] && echo "Bumping SOVERSION for libmbedcrypto in library/Makefile" - sed -e "s/SOEXT_CRYPTO=so.[0-9]\{1,\}/SOEXT_CRYPTO=so.$SO_CRYPTO/g" < library/Makefile > tmp - mv tmp library/Makefile -fi - -[ $VERBOSE ] && echo "Bumping VERSION in include/mbedtls/version.h" -read MAJOR MINOR PATCH <<<$(IFS="."; echo $VERSION) -VERSION_NR="$( printf "0x%02X%02X%02X00" $MAJOR $MINOR $PATCH )" -cat include/mbedtls/version.h | \ - sed -e "s/_VERSION_MAJOR .\{1,\}/_VERSION_MAJOR $MAJOR/" | \ - sed -e "s/_VERSION_MINOR .\{1,\}/_VERSION_MINOR $MINOR/" | \ - sed -e "s/_VERSION_PATCH .\{1,\}/_VERSION_PATCH $PATCH/" | \ - sed -e "s/_VERSION_NUMBER .\{1,\}/_VERSION_NUMBER $VERSION_NR/" | \ - sed -e "s/_VERSION_STRING .\{1,\}/_VERSION_STRING \"$VERSION\"/" | \ - sed -e "s/_VERSION_STRING_FULL .\{1,\}/_VERSION_STRING_FULL \"mbed TLS $VERSION\"/" \ - > tmp -mv tmp include/mbedtls/version.h - -[ $VERBOSE ] && echo "Bumping version in tests/suites/test_suite_version.data" -sed -e "s/version:\".\{1,\}/version:\"$VERSION\"/g" < tests/suites/test_suite_version.data > tmp -mv tmp tests/suites/test_suite_version.data - -[ $VERBOSE ] && echo "Bumping PROJECT_NAME in doxygen/mbedtls.doxyfile and doxygen/input/doc_mainpage.h" -for i in doxygen/mbedtls.doxyfile doxygen/input/doc_mainpage.h; -do - sed -e "s/mbed TLS v[0-9\.]\{1,\}/mbed TLS v$VERSION/g" < $i > tmp - mv tmp $i -done - -[ $VERBOSE ] && echo "Re-generating library/error.c" -scripts/generate_errors.pl - -[ $VERBOSE ] && echo "Re-generating programs/test/query_config.c" -scripts/generate_query_config.pl - -[ $VERBOSE ] && echo "Re-generating library/version_features.c" -scripts/generate_features.pl - -[ $VERBOSE ] && echo "Re-generating visualc files" -scripts/generate_visualc_files.pl - diff --git a/Middlewares/Third_Party/mbed-crypto/scripts/ecc-heap.sh b/Middlewares/Third_Party/mbed-crypto/scripts/ecc-heap.sh deleted file mode 100644 index 94a04cf7..00000000 --- a/Middlewares/Third_Party/mbed-crypto/scripts/ecc-heap.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh - -# Measure heap usage (and performance) of ECC operations with various values of -# the relevant tunable compile-time parameters. -# -# Usage (preferably on a 32-bit platform): -# cmake -D CMAKE_BUILD_TYPE=Release . -# scripts/ecc-heap.sh | tee ecc-heap.log - -set -eu - -CONFIG_H='include/mbedtls/config.h' - -if [ -r $CONFIG_H ]; then :; else - echo "$CONFIG_H not found" >&2 - exit 1 -fi - -if grep -i cmake Makefile >/dev/null; then :; else - echo "Needs Cmake" >&2 - exit 1 -fi - -if git status | grep -F $CONFIG_H >/dev/null 2>&1; then - echo "config.h not clean" >&2 - exit 1 -fi - -CONFIG_BAK=${CONFIG_H}.bak -cp $CONFIG_H $CONFIG_BAK - -cat << EOF >$CONFIG_H -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_MEMORY_BUFFER_ALLOC_C -#define MBEDTLS_MEMORY_DEBUG - -#define MBEDTLS_TIMING_C - -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_ECP_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#define MBEDTLS_ECDSA_C -#define MBEDTLS_ECDH_C - -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED - -#include "check_config.h" - -//#define MBEDTLS_ECP_WINDOW_SIZE 6 -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 -EOF - -for F in 0 1; do - for W in 2 3 4 5 6; do - scripts/config.pl set MBEDTLS_ECP_WINDOW_SIZE $W - scripts/config.pl set MBEDTLS_ECP_FIXED_POINT_OPTIM $F - make benchmark >/dev/null 2>&1 - echo "fixed point optim = $F, max window size = $W" - echo "--------------------------------------------" - programs/test/benchmark - done -done - -# cleanup - -mv $CONFIG_BAK $CONFIG_H -make clean diff --git a/Middlewares/Third_Party/mbed-crypto/scripts/footprint.sh b/Middlewares/Third_Party/mbed-crypto/scripts/footprint.sh deleted file mode 100644 index 697972f3..00000000 --- a/Middlewares/Third_Party/mbed-crypto/scripts/footprint.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/sh -# -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved -# -# Purpose -# -# This script determines ROM size (or code size) for the standard mbed TLS -# configurations, when built for a Cortex M3/M4 target. -# -# Configurations included: -# default include/mbedtls/config.h -# thread configs/config-thread.h -# suite-b configs/config-suite-b.h -# psk configs/config-ccm-psk-tls1_2.h -# -# Usage: footprint.sh -# -set -eu - -CONFIG_H='include/mbedtls/config.h' - -if [ -r $CONFIG_H ]; then :; else - echo "$CONFIG_H not found" >&2 - echo "This script needs to be run from the root of" >&2 - echo "a git checkout or uncompressed tarball" >&2 - exit 1 -fi - -if grep -i cmake Makefile >/dev/null; then - echo "Not compatible with CMake" >&2 - exit 1 -fi - -if which arm-none-eabi-gcc >/dev/null 2>&1; then :; else - echo "You need the ARM-GCC toolchain in your path" >&2 - echo "See https://launchpad.net/gcc-arm-embedded/" >&2 - exit 1 -fi - -ARMGCC_FLAGS='-Os -march=armv7-m -mthumb' -OUTFILE='00-footprint-summary.txt' - -log() -{ - echo "$@" - echo "$@" >> "$OUTFILE" -} - -doit() -{ - NAME="$1" - FILE="$2" - - log "" - log "$NAME ($FILE):" - - cp $CONFIG_H ${CONFIG_H}.bak - if [ "$FILE" != $CONFIG_H ]; then - cp "$FILE" $CONFIG_H - fi - - { - scripts/config.pl unset MBEDTLS_TIMING_C || true - scripts/config.pl unset MBEDTLS_FS_IO || true - scripts/config.pl --force set MBEDTLS_NO_PLATFORM_ENTROPY || true - } >/dev/null 2>&1 - - make clean >/dev/null - CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld \ - CFLAGS="$ARMGCC_FLAGS" make lib >/dev/null - - OUT="size-${NAME}.txt" - arm-none-eabi-size -t library/libmbed*.a > "$OUT" - log "$( head -n1 "$OUT" )" - log "$( tail -n1 "$OUT" )" - - cp ${CONFIG_H}.bak $CONFIG_H -} - -# truncate the file just this time -echo "(generated by $0)" > "$OUTFILE" -echo "" >> "$OUTFILE" - -log "Footprint of standard configurations (minus net_sockets.c, timing.c, fs_io)" -log "for bare-metal ARM Cortex-M3/M4 microcontrollers." - -VERSION_H="include/mbedtls/version.h" -MBEDTLS_VERSION=$( sed -n 's/.*VERSION_STRING *"\(.*\)"/\1/p' $VERSION_H ) -if git rev-parse HEAD >/dev/null; then - GIT_HEAD=$( git rev-parse HEAD | head -c 10 ) - GIT_VERSION=" (git head: $GIT_HEAD)" -else - GIT_VERSION="" -fi - -log "" -log "mbed TLS $MBEDTLS_VERSION$GIT_VERSION" -log "$( arm-none-eabi-gcc --version | head -n1 )" -log "CFLAGS=$ARMGCC_FLAGS" - -doit default include/mbedtls/config.h -doit thread configs/config-thread.h -doit suite-b configs/config-suite-b.h -doit psk configs/config-ccm-psk-tls1_2.h - -zip mbedtls-footprint.zip "$OUTFILE" size-*.txt >/dev/null diff --git a/Middlewares/Third_Party/mbed-crypto/scripts/output_env.sh b/Middlewares/Third_Party/mbed-crypto/scripts/output_env.sh deleted file mode 100644 index 132963c0..00000000 --- a/Middlewares/Third_Party/mbed-crypto/scripts/output_env.sh +++ /dev/null @@ -1,84 +0,0 @@ -#! /usr/bin/env sh - -# output_env.sh -# -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2016, ARM Limited, All Rights Reserved -# -# Purpose -# -# To print out all the relevant information about the development environment. -# -# This includes: -# - architecture of the system -# - type and version of the operating system -# - version of armcc, clang, gcc-arm and gcc compilers -# - version of libc, clang, asan and valgrind if installed - -print_version() -{ - BIN="$1" - shift - ARGS="$1" - shift - FAIL_MSG="$1" - shift - - if ! `type "$BIN" > /dev/null 2>&1`; then - echo "* $FAIL_MSG" - return 0 - fi - - BIN=`which "$BIN"` - VERSION_STR=`$BIN $ARGS 2>&1` - - # Apply all filters - while [ $# -gt 0 ]; do - FILTER="$1" - shift - VERSION_STR=`echo "$VERSION_STR" | $FILTER` - done - - echo "* ${BIN##*/}: $BIN: $VERSION_STR" -} - -print_version "uname" "-a" "" -echo - -if [ "${RUN_ARMCC:-1}" -ne 0 ]; then - : "${ARMC5_CC:=armcc}" - print_version "$ARMC5_CC" "--vsn" "armcc not found!" "head -n 2" - echo - - : "${ARMC6_CC:=armclang}" - print_version "$ARMC6_CC" "--vsn" "armclang not found!" "head -n 2" - echo -fi - -print_version "arm-none-eabi-gcc" "--version" "gcc-arm not found!" "head -n 1" -echo - -print_version "gcc" "--version" "gcc not found!" "head -n 1" -echo - -print_version "clang" "--version" "clang not found" "head -n 2" -echo - -print_version "ldd" "--version" \ - "No ldd present: can't determine libc version!" \ - "head -n 1" -echo - -print_version "valgrind" "--version" "valgrind not found!" -echo - -if `hash dpkg > /dev/null 2>&1`; then - echo "* asan:" - dpkg -s libasan2 2> /dev/null | grep -i version - dpkg -s libasan1 2> /dev/null | grep -i version - dpkg -s libasan0 2> /dev/null | grep -i version -else - echo "* No dpkg present: can't determine asan version!" -fi -echo diff --git a/Middlewares/Third_Party/mbed-crypto/scripts/tmp_ignore_makefiles.sh b/Middlewares/Third_Party/mbed-crypto/scripts/tmp_ignore_makefiles.sh deleted file mode 100644 index df9450e1..00000000 --- a/Middlewares/Third_Party/mbed-crypto/scripts/tmp_ignore_makefiles.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Temporarily (de)ignore Makefiles generated by CMake to allow easier -# git development - -IGNORE="" - -# Parse arguments -# -until [ -z "$1" ] -do - case "$1" in - -u|--undo) - IGNORE="0" - ;; - -v|--verbose) - # Be verbose - VERBOSE="1" - ;; - -h|--help) - # print help - echo "Usage: $0" - echo -e " -h|--help\t\tPrint this help." - echo -e " -u|--undo\t\tRemove ignores and continue tracking." - echo -e " -v|--verbose\t\tVerbose." - exit 1 - ;; - *) - # print error - echo "Unknown argument: '$1'" - exit 1 - ;; - esac - shift -done - -if [ "X" = "X$IGNORE" ]; -then - [ $VERBOSE ] && echo "Ignoring Makefiles" - git update-index --assume-unchanged Makefile library/Makefile programs/Makefile tests/Makefile -else - [ $VERBOSE ] && echo "Tracking Makefiles" - git update-index --no-assume-unchanged Makefile library/Makefile programs/Makefile tests/Makefile -fi diff --git a/Middlewares/Third_Party/mbed-crypto/tests/git-scripts/pre-push.sh b/Middlewares/Third_Party/mbed-crypto/tests/git-scripts/pre-push.sh deleted file mode 100644 index 86edf5a3..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/git-scripts/pre-push.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# pre-push.sh -# -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2017, ARM Limited, All Rights Reserved -# -# Purpose -# -# Called by "git push" after it has checked the remote status, but before anything has been -# pushed. If this script exits with a non-zero status nothing will be pushed. -# This script can also be used independently, not using git. -# -# This hook is called with the following parameters: -# -# $1 -- Name of the remote to which the push is being done -# $2 -- URL to which the push is being done -# -# If pushing without using a named remote those arguments will be equal. -# -# Information about the commits which are being pushed is supplied as lines to -# the standard input in the form: -# -# -# - -REMOTE="$1" -URL="$2" - -echo "REMOTE is $REMOTE" -echo "URL is $URL" - -set -eu - -run_test() -{ - TEST=$1 - echo "running '$TEST'" - if ! `$TEST > /dev/null 2>&1`; then - echo "test '$TEST' failed" - return 1 - fi -} - -run_test ./tests/scripts/check-doxy-blocks.pl -run_test ./tests/scripts/check-names.sh -run_test ./tests/scripts/check-generated-files.sh -run_test ./tests/scripts/check-files.py -run_test ./tests/scripts/doxygen.sh diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/all.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/all.sh deleted file mode 100644 index b38c7d45..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/all.sh +++ /dev/null @@ -1,1145 +0,0 @@ -#! /usr/bin/env sh - -# all.sh -# -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2014-2017, ARM Limited, All Rights Reserved - - - -################################################################ -#### Documentation -################################################################ - -# Purpose -# ------- -# -# To run all tests possible or available on the platform. -# -# Notes for users -# --------------- -# -# Warning: the test is destructive. It includes various build modes and -# configurations, and can and will arbitrarily change the current CMake -# configuration. The following files must be committed into git: -# * include/mbedtls/config.h -# * Makefile, library/Makefile, programs/Makefile, tests/Makefile -# After running this script, the CMake cache will be lost and CMake -# will no longer be initialised. -# -# The script assumes the presence of a number of tools: -# * Basic Unix tools (Windows users note: a Unix-style find must be before -# the Windows find in the PATH) -# * Perl -# * GNU Make -# * CMake -# * GCC and Clang (recent enough for using ASan with gcc and MemSan with clang, or valgrind) -# * G++ -# * arm-gcc and mingw-gcc -# * ArmCC 5 and ArmCC 6, unless invoked with --no-armcc -# See the invocation of check_tools below for details. -# -# This script must be invoked from the toplevel directory of a git -# working copy of Mbed TLS. -# -# Note that the output is not saved. You may want to run -# script -c tests/scripts/all.sh -# or -# tests/scripts/all.sh >all.log 2>&1 -# -# Notes for maintainers -# --------------------- -# -# The bulk of the code is organized into functions that follow one of the -# following naming conventions: -# * pre_XXX: things to do before running the tests, in order. -# * component_XXX: independent components. They can be run in any order. -# * component_check_XXX: quick tests that aren't worth parallelizing. -# * component_build_XXX: build things but don't run them. -# * component_test_XXX: build and test. -# * support_XXX: if support_XXX exists and returns false then -# component_XXX is not run by default. -# * post_XXX: things to do after running the tests. -# * other: miscellaneous support functions. -# -# Each component must start by invoking `msg` with a short informative message. -# -# The framework performs some cleanup tasks after each component. This -# means that components can assume that the working directory is in a -# cleaned-up state, and don't need to perform the cleanup themselves. -# * Run `make clean`. -# * Restore `include/mbedtks/config.h` from a backup made before running -# the component. -# * Check out `Makefile`, `library/Makefile`, `programs/Makefile` and -# `tests/Makefile` from git. This cleans up after an in-tree use of -# CMake. -# -# Any command that is expected to fail must be protected so that the -# script keeps running in --keep-going mode despite `set -e`. In keep-going -# mode, if a protected command fails, this is logged as a failure and the -# script will exit with a failure status once it has run all components. -# Commands can be protected in any of the following ways: -# * `make` is a function which runs the `make` command with protection. -# Note that you must write `make VAR=value`, not `VAR=value make`, -# because the `VAR=value make` syntax doesn't work with functions. -# * Put `report_status` before the command to protect it. -# * Put `if_build_successful` before a command. This protects it, and -# additionally skips it if a prior invocation of `make` in the same -# component failed. -# -# The tests are roughly in order from fastest to slowest. This doesn't -# have to be exact, but in general you should add slower tests towards -# the end and fast checks near the beginning. - - - -################################################################ -#### Initialization and command line parsing -################################################################ - -# Abort on errors (and uninitialised variables) -set -eu - -pre_check_environment () { - if [ -d library -a -d include -a -d tests ]; then :; else - echo "Must be run from mbed TLS root" >&2 - exit 1 - fi -} - -pre_initialize_variables () { - CONFIG_H='include/mbedtls/config.h' - CONFIG_BAK="$CONFIG_H.bak" - - FORCE=0 - KEEP_GOING=0 - - # Default commands, can be overridden by the environment - : ${OUT_OF_SOURCE_DIR:=./mbedtls_out_of_source_build} - : ${ARMC5_BIN_DIR:=/usr/bin} - : ${ARMC6_BIN_DIR:=/usr/bin} - - # if MAKEFLAGS is not set add the -j option to speed up invocations of make - if [ -z "${MAKEFLAGS+set}" ]; then - export MAKEFLAGS="-j" - fi - - # Include more verbose output for failing tests run by CMake - export CTEST_OUTPUT_ON_FAILURE=1 - - # Gather the list of available components. These are the functions - # defined in this script whose name starts with "component_". - # Parse the script with sed, because in sh there is no way to list - # defined functions. - ALL_COMPONENTS=$(sed -n 's/^ *component_\([0-9A-Z_a-z]*\) *().*/\1/p' <"$0") - - # Exclude components that are not supported on this platform. - SUPPORTED_COMPONENTS= - for component in $ALL_COMPONENTS; do - case $(type "support_$component" 2>&1) in - *' function'*) - if ! support_$component; then continue; fi;; - esac - SUPPORTED_COMPONENTS="$SUPPORTED_COMPONENTS $component" - done -} - -# Test whether the component $1 is included in the command line patterns. -is_component_included() -{ - set -f - for pattern in $COMMAND_LINE_COMPONENTS; do - set +f - case ${1#component_} in $pattern) return 0;; esac - done - set +f - return 1 -} - -usage() -{ - cat < Directory used for CMake out-of-source build tests. - --random-seed Use a random seed value for randomized tests (default). - -r|--release-test Run this script in release mode. This fixes the seed value to 1. - -s|--seed Integer seed value to use for this test run. - -Tool path options: - --armc5-bin-dir= ARM Compiler 5 bin directory. - --armc6-bin-dir= ARM Compiler 6 bin directory. -EOF -} - -# remove built files as well as the cmake cache/config -cleanup() -{ - if [ -n "${MBEDTLS_ROOT_DIR+set}" ]; then - cd "$MBEDTLS_ROOT_DIR" - fi - - command make clean - - # Remove CMake artefacts - find . -name .git -prune -o \ - -iname CMakeFiles -exec rm -rf {} \+ -o \ - \( -iname cmake_install.cmake -o \ - -iname CTestTestfile.cmake -o \ - -iname CMakeCache.txt \) -exec rm {} \+ - # Recover files overwritten by in-tree CMake builds - rm -f include/Makefile include/mbedtls/Makefile programs/*/Makefile - git update-index --no-skip-worktree Makefile library/Makefile programs/Makefile tests/Makefile - git checkout -- Makefile library/Makefile programs/Makefile tests/Makefile - - if [ -f "$CONFIG_BAK" ]; then - mv "$CONFIG_BAK" "$CONFIG_H" - fi -} - -# Executed on exit. May be redefined depending on command line options. -final_report () { - : -} - -fatal_signal () { - cleanup - final_report $1 - trap - $1 - kill -$1 $$ -} - -trap 'fatal_signal HUP' HUP -trap 'fatal_signal INT' INT -trap 'fatal_signal TERM' TERM - -msg() -{ - if [ -n "${current_component:-}" ]; then - current_section="${current_component#component_}: $1" - else - current_section="$1" - fi - echo "" - echo "******************************************************************" - echo "* $current_section " - printf "* "; date - echo "******************************************************************" -} - -armc6_build_test() -{ - FLAGS="$1" - - msg "build: ARM Compiler 6 ($FLAGS), make" - ARM_TOOL_VARIANT="ult" CC="$ARMC6_CC" AR="$ARMC6_AR" CFLAGS="$FLAGS" \ - WARNING_CFLAGS='-xc -std=c99' make lib - make clean -} - -err_msg() -{ - echo "$1" >&2 -} - -check_tools() -{ - for TOOL in "$@"; do - if ! `type "$TOOL" >/dev/null 2>&1`; then - err_msg "$TOOL not found!" - exit 1 - fi - done -} - -check_headers_in_cpp () { - ls include/mbedtls | grep "\.h$" >headers.txt - &2 "Unknown option: $1" - echo >&2 "Run $0 --help for usage." - exit 120 - ;; - *) COMMAND_LINE_COMPONENTS="$COMMAND_LINE_COMPONENTS $1";; - esac - shift - done - - # With no list of components, run everything. - if [ -z "$COMMAND_LINE_COMPONENTS" ]; then - all_except=1 - fi - - # --no-armcc is a legacy option. The modern way is --except '*_armcc*'. - # Ignore it if components are listed explicitly on the command line. - if [ -n "$no_armcc" ] && [ $all_except -eq 1 ]; then - COMMAND_LINE_COMPONENTS="$COMMAND_LINE_COMPONENTS *_armcc*" - fi - - # Build the list of components to run. - RUN_COMPONENTS= - for component in $SUPPORTED_COMPONENTS; do - if is_component_included "$component"; [ $? -eq $all_except ]; then - RUN_COMPONENTS="$RUN_COMPONENTS $component" - fi - done - - unset all_except - unset no_armcc -} - -pre_check_git () { - if [ $FORCE -eq 1 ]; then - rm -rf "$OUT_OF_SOURCE_DIR" - git checkout-index -f -q $CONFIG_H - cleanup - else - - if [ -d "$OUT_OF_SOURCE_DIR" ]; then - echo "Warning - there is an existing directory at '$OUT_OF_SOURCE_DIR'" >&2 - echo "You can either delete this directory manually, or force the test by rerunning" - echo "the script as: $0 --force --out-of-source-dir $OUT_OF_SOURCE_DIR" - exit 1 - fi - - if ! git diff --quiet include/mbedtls/config.h; then - err_msg "Warning - the configuration file 'include/mbedtls/config.h' has been edited. " - echo "You can either delete or preserve your work, or force the test by rerunning the" - echo "script as: $0 --force" - exit 1 - fi - fi -} - -pre_check_seedfile () { - if [ ! -f "./tests/seedfile" ]; then - dd if=/dev/urandom of=./tests/seedfile bs=32 count=1 - fi -} - -pre_setup_keep_going () { - failure_summary= - failure_count=0 - start_red= - end_color= - if [ -t 1 ]; then - case "${TERM:-}" in - *color*|cygwin|linux|rxvt*|screen|[Eex]term*) - start_red=$(printf '\033[31m') - end_color=$(printf '\033[0m') - ;; - esac - fi - record_status () { - if "$@"; then - last_status=0 - else - last_status=$? - text="$current_section: $* -> $last_status" - failure_summary="$failure_summary -$text" - failure_count=$((failure_count + 1)) - echo "${start_red}^^^^$text^^^^${end_color}" - fi - } - make () { - case "$*" in - *test|*check) - if [ $build_status -eq 0 ]; then - record_status command make "$@" - else - echo "(skipped because the build failed)" - fi - ;; - *) - record_status command make "$@" - build_status=$last_status - ;; - esac - } - final_report () { - if [ $failure_count -gt 0 ]; then - echo - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - echo "${start_red}FAILED: $failure_count${end_color}$failure_summary" - echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - exit 1 - elif [ -z "${1-}" ]; then - echo "SUCCESS :)" - fi - if [ -n "${1-}" ]; then - echo "Killed by SIG$1." - fi - } -} - -if_build_succeeded () { - if [ $build_status -eq 0 ]; then - record_status "$@" - fi -} - -# to be used instead of ! for commands run with -# record_status or if_build_succeeded -not() { - ! "$@" -} - -pre_print_configuration () { - msg "info: $0 configuration" - echo "FORCE: $FORCE" - echo "ARMC5_BIN_DIR: $ARMC5_BIN_DIR" - echo "ARMC6_BIN_DIR: $ARMC6_BIN_DIR" -} - -# Make sure the tools we need are available. -pre_check_tools () { - # Build the list of variables to pass to output_env.sh. - set env - - case " $RUN_COMPONENTS " in - *_doxygen[_\ ]*) check_tools "doxygen" "dot";; - esac - - case " $RUN_COMPONENTS " in - *_arm_none_eabi_gcc[_\ ]*) check_tools "arm-none-eabi-gcc";; - esac - - case " $RUN_COMPONENTS " in - *_mingw[_\ ]*) check_tools "i686-w64-mingw32-gcc";; - esac - - case " $RUN_COMPONENTS " in - *" test_zeroize "*) check_tools "gdb";; - esac - - case " $RUN_COMPONENTS " in - *_armcc*) - ARMC5_CC="$ARMC5_BIN_DIR/armcc" - ARMC5_AR="$ARMC5_BIN_DIR/armar" - ARMC6_CC="$ARMC6_BIN_DIR/armclang" - ARMC6_AR="$ARMC6_BIN_DIR/armar" - check_tools "$ARMC5_CC" "$ARMC5_AR" "$ARMC6_CC" "$ARMC6_AR";; - esac - - msg "info: output_env.sh" - case $RUN_COMPONENTS in - *_armcc*) - set "$@" ARMC5_CC="$ARMC5_CC" ARMC6_CC="$ARMC6_CC" RUN_ARMCC=1;; - *) set "$@" RUN_ARMCC=0;; - esac - "$@" scripts/output_env.sh -} - - - -################################################################ -#### Basic checks -################################################################ - -# -# Test Suites to be executed -# -# The test ordering tries to optimize for the following criteria: -# 1. Catch possible problems early, by running first tests that run quickly -# and/or are more likely to fail than others (eg I use Clang most of the -# time, so start with a GCC build). -# 2. Minimize total running time, by avoiding useless rebuilds -# -# Indicative running times are given for reference. - -component_check_recursion () { - msg "test: recursion.pl" # < 1s - record_status tests/scripts/recursion.pl library/*.c -} - -component_check_generated_files () { - msg "test: freshness of generated source files" # < 1s - record_status tests/scripts/check-generated-files.sh -} - -component_check_doxy_blocks () { - msg "test: doxygen markup outside doxygen blocks" # < 1s - record_status tests/scripts/check-doxy-blocks.pl -} - -component_check_files () { - msg "test: check-files.py" # < 1s - record_status tests/scripts/check-files.py -} - -component_check_names () { - msg "test/build: declared and exported names" # < 3s - record_status tests/scripts/check-names.sh -} - -component_check_doxygen_warnings () { - msg "test: doxygen warnings" # ~ 3s - record_status tests/scripts/doxygen.sh -} - - -################################################################ -#### Build and test many configurations and targets -################################################################ - -component_test_default_out_of_box () { - msg "build: make, default config (out-of-box)" # ~1min - make - - msg "test: main suites make, default config (out-of-box)" # ~10s - make test - - msg "selftest: make, default config (out-of-box)" # ~10s - programs/test/selftest -} - -component_test_default_cmake_gcc_asan () { - msg "build: cmake, gcc, ASan" # ~ 1 min 50s - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . - make - - msg "test: main suites (inc. selftests) (ASan build)" # ~ 50s - make test -} - -component_test_ref_configs () { - msg "test/build: ref-configs (ASan build)" # ~ 6 min 20s - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . - record_status tests/scripts/test-ref-configs.pl -} - -component_test_rsa_no_crt () { - msg "build: Default + RSA_NO_CRT (ASan build)" # ~ 6 min - scripts/config.pl set MBEDTLS_RSA_NO_CRT - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . - make - - msg "test: RSA_NO_CRT - main suites (inc. selftests) (ASan build)" # ~ 50s - make test -} - -component_test_new_ecdh_context () { - msg "build: new ECDH context (ASan build)" # ~ 6 min - scripts/config.pl unset MBEDTLS_ECDH_LEGACY_CONTEXT - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . - make - - msg "test: new ECDH context - main suites (inc. selftests) (ASan build)" # ~ 50s - make test -} - -component_test_full_cmake_clang () { - msg "build: cmake, full config, clang" # ~ 50s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests - CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On . - make - - msg "test: main suites (full config)" # ~ 5s - make test - - msg "test: psa_constant_names (full config)" # ~ 1s - record_status tests/scripts/test_psa_constant_names.py -} - -component_build_deprecated () { - msg "build: make, full config + DEPRECATED_WARNING, gcc -O" # ~ 30s - scripts/config.pl full - scripts/config.pl set MBEDTLS_DEPRECATED_WARNING - # Build with -O -Wextra to catch a maximum of issues. - make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' lib programs - make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests - - msg "build: make, full config + DEPRECATED_REMOVED, clang -O" # ~ 30s - # No cleanup, just tweak the configuration and rebuild - make clean - scripts/config.pl unset MBEDTLS_DEPRECATED_WARNING - scripts/config.pl set MBEDTLS_DEPRECATED_REMOVED - # Build with -O -Wextra to catch a maximum of issues. - make CC=clang CFLAGS='-O -Werror -Wall -Wextra' lib programs - make CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests -} - - -component_test_depends_curves () { - msg "test/build: curves.pl (gcc)" # ~ 4 min - record_status tests/scripts/curves.pl -} - -component_test_depends_hashes () { - msg "test/build: depends-hashes.pl (gcc)" # ~ 2 min - record_status tests/scripts/depends-hashes.pl -} - -component_test_depends_pkalgs () { - msg "test/build: depends-pkalgs.pl (gcc)" # ~ 2 min - record_status tests/scripts/depends-pkalgs.pl -} - -component_build_default_make_gcc_and_cxx () { - msg "build: Unix make, -Os (gcc)" # ~ 30s - make CC=gcc CFLAGS='-Werror -Wall -Wextra -Os' - - msg "test: verify header list in cpp_dummy_build.cpp" - record_status check_headers_in_cpp - - msg "build: Unix make, incremental g++" - make TEST_CPP=1 -} - -component_test_use_psa_crypto_full_cmake_asan() { - # MBEDTLS_USE_PSA_CRYPTO: run the same set of tests as basic-build-test.sh - msg "build: cmake, full config + MBEDTLS_USE_PSA_CRYPTO, ASan" - scripts/config.pl full - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests - scripts/config.pl unset MBEDTLS_ECP_RESTARTABLE # restartable ECC not supported through PSA - scripts/config.pl set MBEDTLS_PSA_CRYPTO_C - scripts/config.pl set MBEDTLS_USE_PSA_CRYPTO - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . - make - - msg "test: main suites (MBEDTLS_USE_PSA_CRYPTO)" - make test -} - -component_test_check_params_without_platform () { - msg "build+test: MBEDTLS_CHECK_PARAMS without MBEDTLS_PLATFORM_C" - scripts/config.pl full # includes CHECK_PARAMS - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C - scripts/config.pl unset MBEDTLS_PLATFORM_EXIT_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_FPRINTF_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_MEMORY - scripts/config.pl unset MBEDTLS_PLATFORM_PRINTF_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl unset MBEDTLS_PLATFORM_C - make CC=gcc CFLAGS='-Werror -O1' all test -} - -component_test_check_params_silent () { - msg "build+test: MBEDTLS_CHECK_PARAMS with alternative MBEDTLS_PARAM_FAILED()" - scripts/config.pl full # includes CHECK_PARAMS - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests - sed -i 's/.*\(#define MBEDTLS_PARAM_FAILED( cond )\).*/\1/' "$CONFIG_H" - make CC=gcc CFLAGS='-Werror -O1' all test -} - -component_test_no_platform () { - # Full configuration build, without platform support, file IO and net sockets. - # This should catch missing mbedtls_printf definitions, and by disabling file - # IO, it should catch missing '#include ' - msg "build: full config except platform/fsio/net, make, gcc, C99" # ~ 30s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_PLATFORM_C - scripts/config.pl unset MBEDTLS_PLATFORM_MEMORY - scripts/config.pl unset MBEDTLS_PLATFORM_PRINTF_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_FPRINTF_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT - scripts/config.pl unset MBEDTLS_PLATFORM_EXIT_ALT - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C - scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19, - # to re-enable platform integration features otherwise disabled in C99 builds - make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' test -} - -component_build_no_std_function () { - # catch compile bugs in _uninit functions - msg "build: full config with NO_STD_FUNCTION, make, gcc" # ~ 30s - scripts/config.pl full - scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' -} - -component_test_null_entropy () { - msg "build: default config with MBEDTLS_TEST_NULL_ENTROPY (ASan build)" - scripts/config.pl set MBEDTLS_TEST_NULL_ENTROPY - scripts/config.pl set MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - scripts/config.pl set MBEDTLS_ENTROPY_C - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl unset MBEDTLS_ENTROPY_HARDWARE_ALT - scripts/config.pl unset MBEDTLS_HAVEGE_C - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan -D UNSAFE_BUILD=ON . - make - - msg "test: MBEDTLS_TEST_NULL_ENTROPY - main suites (inc. selftests) (ASan build)" - make test -} - -component_test_platform_calloc_macro () { - msg "build: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)" - scripts/config.pl set MBEDTLS_PLATFORM_MEMORY - scripts/config.pl set MBEDTLS_PLATFORM_CALLOC_MACRO calloc - scripts/config.pl set MBEDTLS_PLATFORM_FREE_MACRO free - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . - make - - msg "test: MBEDTLS_PLATFORM_{CALLOC/FREE}_MACRO enabled (ASan build)" - make test -} - -component_test_aes_fewer_tables () { - msg "build: default config with AES_FEWER_TABLES enabled" - scripts/config.pl set MBEDTLS_AES_FEWER_TABLES - make CC=gcc CFLAGS='-Werror -Wall -Wextra' - - msg "test: AES_FEWER_TABLES" - make test -} - -component_test_aes_rom_tables () { - msg "build: default config with AES_ROM_TABLES enabled" - scripts/config.pl set MBEDTLS_AES_ROM_TABLES - make CC=gcc CFLAGS='-Werror -Wall -Wextra' - - msg "test: AES_ROM_TABLES" - make test -} - -component_test_aes_fewer_tables_and_rom_tables () { - msg "build: default config with AES_ROM_TABLES and AES_FEWER_TABLES enabled" - scripts/config.pl set MBEDTLS_AES_FEWER_TABLES - scripts/config.pl set MBEDTLS_AES_ROM_TABLES - make CC=gcc CFLAGS='-Werror -Wall -Wextra' - - msg "test: AES_FEWER_TABLES + AES_ROM_TABLES" - make test -} - -component_test_make_shared () { - msg "build/test: make shared" # ~ 40s - make SHARED=1 all check -} - -component_test_m32_o0 () { - # Build once with -O0, to compile out the i386 specific inline assembly - msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s - scripts/config.pl full - make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address' - - msg "test: i386, make, gcc -O0 (ASan build)" - make test -} -support_test_m32_o0 () { - case $(uname -m) in - *64*) true;; - *) false;; - esac -} - -component_test_m32_o1 () { - # Build again with -O1, to compile in the i386 specific inline assembly - msg "build: i386, make, gcc -O1 (ASan build)" # ~ 30s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C - scripts/config.pl unset MBEDTLS_MEMORY_DEBUG - make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address' - - msg "test: i386, make, gcc -O1 (ASan build)" - make test -} -support_test_m32_o1 () { - support_test_m32_o0 "$@" -} - -component_test_mx32 () { - msg "build: 64-bit ILP32, make, gcc" # ~ 30s - scripts/config.pl full - make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32' - - msg "test: 64-bit ILP32, make, gcc" - make test -} -support_test_mx32 () { - case $(uname -m) in - amd64|x86_64) true;; - *) false;; - esac -} - -component_test_min_mpi_window_size () { - msg "build: Default + MBEDTLS_MPI_WINDOW_SIZE=1 (ASan build)" # ~ 10s - scripts/config.pl set MBEDTLS_MPI_WINDOW_SIZE 1 - CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . - make - - msg "test: MBEDTLS_MPI_WINDOW_SIZE=1 - main suites (inc. selftests) (ASan build)" # ~ 10s - make test -} - -component_test_have_int32 () { - msg "build: gcc, force 32-bit bignum limbs" - scripts/config.pl unset MBEDTLS_HAVE_ASM - scripts/config.pl unset MBEDTLS_AESNI_C - scripts/config.pl unset MBEDTLS_PADLOCK_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32' - - msg "test: gcc, force 32-bit bignum limbs" - make test -} - -component_test_have_int64 () { - msg "build: gcc, force 64-bit bignum limbs" - scripts/config.pl unset MBEDTLS_HAVE_ASM - scripts/config.pl unset MBEDTLS_AESNI_C - scripts/config.pl unset MBEDTLS_PADLOCK_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64' - - msg "test: gcc, force 64-bit bignum limbs" - make test -} - -component_test_no_udbl_division () { - msg "build: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests - scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION - make CFLAGS='-Werror -O1' - - msg "test: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s - make test -} - -component_test_no_64bit_multiplication () { - msg "build: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests - scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION - make CFLAGS='-Werror -O1' - - msg "test: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s - make test -} - -component_build_arm_none_eabi_gcc () { - msg "build: arm-none-eabi-gcc, make" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit - make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib -} - -component_build_arm_none_eabi_gcc_no_udbl_division () { - msg "build: arm-none-eabi-gcc -DMBEDTLS_NO_UDBL_DIVISION, make" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit - scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION - make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib - echo "Checking that software 64-bit division is not required" - if_build_succeeded not grep __aeabi_uldiv library/*.o -} - -component_build_arm_none_eabi_gcc_no_64bit_multiplication () { - msg "build: arm-none-eabi-gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit - scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION - make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -O1 -march=armv6-m -mthumb' lib - echo "Checking that software 64-bit multiplication is not required" - if_build_succeeded not grep __aeabi_lmul library/*.o -} - -component_build_armcc () { - msg "build: ARM Compiler 5, make" - scripts/config.pl full - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C - scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl unset MBEDTLS_HAVE_TIME - scripts/config.pl unset MBEDTLS_HAVE_TIME_DATE - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_DEPRECATED_WARNING - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit - scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT # depends on MBEDTLS_HAVE_TIME - - make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib - make clean - - # ARM Compiler 6 - Target ARMv7-A - armc6_build_test "--target=arm-arm-none-eabi -march=armv7-a" - - # ARM Compiler 6 - Target ARMv7-M - armc6_build_test "--target=arm-arm-none-eabi -march=armv7-m" - - # ARM Compiler 6 - Target ARMv8-A - AArch32 - armc6_build_test "--target=arm-arm-none-eabi -march=armv8.2-a" - - # ARM Compiler 6 - Target ARMv8-M - armc6_build_test "--target=arm-arm-none-eabi -march=armv8-m.main" - - # ARM Compiler 6 - Target ARMv8-A - AArch64 - armc6_build_test "--target=aarch64-arm-none-eabi -march=armv8.2-a" -} - -component_build_mingw () { - msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s - make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs - - # note Make tests only builds the tests, but doesn't run them - make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror' WINDOWS_BUILD=1 tests - make WINDOWS_BUILD=1 clean - - msg "build: Windows cross build - mingw64, make (DLL)" # ~ 30s - make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 lib programs - make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 tests - make WINDOWS_BUILD=1 clean -} -support_build_mingw() { - case $(i686-w64-mingw32-gcc -dumpversion) in - [0-5]*) false;; - *) true;; - esac -} - -component_test_memsan () { - msg "build: MSan (clang)" # ~ 1 min 20s - scripts/config.pl unset MBEDTLS_AESNI_C # memsan doesn't grok asm - CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan . - make - - msg "test: main suites (MSan)" # ~ 10s - make test -} - -component_test_valgrind () { - msg "build: Release (clang)" - CC=clang cmake -D CMAKE_BUILD_TYPE:String=Release . - make - - msg "test: main suites valgrind (Release)" - make memcheck -} - -component_test_cmake_out_of_source () { - msg "build: cmake 'out-of-source' build" - MBEDTLS_ROOT_DIR="$PWD" - mkdir "$OUT_OF_SOURCE_DIR" - cd "$OUT_OF_SOURCE_DIR" - cmake "$MBEDTLS_ROOT_DIR" - make - - msg "test: cmake 'out-of-source' build" - make test - - cd "$MBEDTLS_ROOT_DIR" - rm -rf "$OUT_OF_SOURCE_DIR" - unset MBEDTLS_ROOT_DIR -} - -component_test_zeroize () { - # Test that the function mbedtls_platform_zeroize() is not optimized away by - # different combinations of compilers and optimization flags by using an - # auxiliary GDB script. Unfortunately, GDB does not return error values to the - # system in all cases that the script fails, so we must manually search the - # output to check whether the pass string is present and no failure strings - # were printed. - - # Don't try to disable ASLR. We don't care about ASLR here. We do care - # about a spurious message if Gdb tries and fails, so suppress that. - gdb_disable_aslr= - if [ -z "$(gdb -batch -nw -ex 'set disable-randomization off' 2>&1)" ]; then - gdb_disable_aslr='set disable-randomization off' - fi - - for optimization_flag in -O2 -O3 -Ofast -Os; do - for compiler in clang gcc; do - msg "test: $compiler $optimization_flag, mbedtls_platform_zeroize()" - make programs CC="$compiler" DEBUG=1 CFLAGS="$optimization_flag" - if_build_succeeded gdb -ex "$gdb_disable_aslr" -x tests/scripts/test_zeroize.gdb -nw -batch -nx 2>&1 | tee test_zeroize.log - if_build_succeeded grep "The buffer was correctly zeroized" test_zeroize.log - if_build_succeeded not grep -i "error" test_zeroize.log - rm -f test_zeroize.log - make clean - done - done - - unset gdb_disable_aslr -} - -support_check_python_files () { - type pylint3 >/dev/null 2>/dev/null -} -component_check_python_files () { - msg "Lint: Python scripts" - record_status tests/scripts/check-python-files.sh -} - -component_check_generate_test_code () { - msg "uint test: generate_test_code.py" - record_status ./tests/scripts/test_generate_test_code.py -} - -################################################################ -#### Termination -################################################################ - -post_report () { - msg "Done, cleaning up" - cleanup - - final_report -} - - - -################################################################ -#### Run all the things -################################################################ - -# Run one component and clean up afterwards. -run_component () { - # Back up the configuration in case the component modifies it. - # The cleanup function will restore it. - cp -p "$CONFIG_H" "$CONFIG_BAK" - current_component="$1" - "$@" - cleanup -} - -# Preliminary setup -pre_check_environment -pre_initialize_variables -pre_parse_command_line "$@" - -pre_check_git -pre_check_seedfile - -build_status=0 -if [ $KEEP_GOING -eq 1 ]; then - pre_setup_keep_going -else - record_status () { - "$@" - } -fi -pre_print_configuration -pre_check_tools -cleanup - -# Run the requested tests. -for component in $RUN_COMPONENTS; do - run_component "component_$component" -done - -# We're done. -post_report diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/basic-build-test.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/basic-build-test.sh deleted file mode 100644 index a653001e..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/basic-build-test.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/sh - -# basic-build-tests.sh -# -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2016, ARM Limited, All Rights Reserved -# -# Purpose -# -# Executes the basic test suites, captures the results, and generates a simple -# test report and code coverage report. -# -# The tests include: -# * Unit tests - executed using tests/scripts/run-test-suite.pl -# * Self-tests - executed using the test suites above -# -# The tests focus on functionality and do not consider performance. -# -# Note the tests self-adapt due to configurations in include/mbedtls/config.h -# which can lead to some tests being skipped, and can cause the number of -# available tests to fluctuate. -# -# This script has been written to be generic and should work on any shell. -# -# Usage: basic-build-tests.sh -# - -# Abort on errors (and uninitiliased variables) -set -eu - -if [ -d library -a -d include -a -d tests ]; then :; else - echo "Must be run from mbed TLS root" >&2 - exit 1 -fi - -CONFIG_H='include/mbedtls/config.h' -CONFIG_BAK="$CONFIG_H.bak" - -# Step 0 - print build environment info -scripts/output_env.sh -echo - -# Step 1 - Make and instrumented build for code coverage -export CFLAGS=' --coverage -g3 -O0 ' -make clean -cp "$CONFIG_H" "$CONFIG_BAK" -scripts/config.pl full -scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE -make -j - - -# Step 2 - Execute the tests -TEST_OUTPUT=out_${PPID} -cd tests - -# Step 2a - Unit Tests -perl scripts/run-test-suites.pl -v 2 |tee unit-test-$TEST_OUTPUT -echo - -# Step 3 - Process the coverage report -cd .. -make lcov |tee tests/cov-$TEST_OUTPUT - - -# Step 4 - Summarise the test report -echo -echo "=========================================================================" -echo "Test Report Summary" -echo - -cd tests - -# Step 4a - Unit tests -echo "Unit tests - tests/scripts/run-test-suites.pl" - -PASSED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/test cases passed :[\t]*\([0-9]*\)/\1/p'| tr -d ' ') -SKIPPED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/skipped :[ \t]*\([0-9]*\)/\1/p'| tr -d ' ') -TOTAL_SUITES=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/.* (\([0-9]*\) .*, [0-9]* tests run)/\1/p'| tr -d ' ') -FAILED_TESTS=$(tail -n6 unit-test-$TEST_OUTPUT|sed -n -e 's/failed :[\t]*\([0-9]*\)/\1/p' |tr -d ' ') - -echo "No test suites : $TOTAL_SUITES" -echo "Passed : $PASSED_TESTS" -echo "Failed : $FAILED_TESTS" -echo "Skipped : $SKIPPED_TESTS" -echo "Total exec'd tests : $(($PASSED_TESTS + $FAILED_TESTS))" -echo "Total avail tests : $(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS))" -echo - -TOTAL_PASS=$PASSED_TESTS -TOTAL_FAIL=$FAILED_TESTS -TOTAL_SKIP=$SKIPPED_TESTS -TOTAL_AVAIL=$(($PASSED_TESTS + $FAILED_TESTS + $SKIPPED_TESTS)) -TOTAL_EXED=$(($PASSED_TESTS + $FAILED_TESTS)) - - -# Step 4d - Grand totals -echo "-------------------------------------------------------------------------" -echo "Total tests" - -echo "Total Passed : $TOTAL_PASS" -echo "Total Failed : $TOTAL_FAIL" -echo "Total Skipped : $TOTAL_SKIP" -echo "Total exec'd tests : $TOTAL_EXED" -echo "Total avail tests : $TOTAL_AVAIL" -echo - - -# Step 4e - Coverage -echo "Coverage" - -LINES_TESTED=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ lines......: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* lines)/\1/p') -LINES_TOTAL=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ lines......: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) lines)/\1/p') -FUNCS_TESTED=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ functions..: [0-9]*.[0-9]% (\([0-9]*\) of [0-9]* functions)$/\1/p') -FUNCS_TOTAL=$(tail -n3 cov-$TEST_OUTPUT|sed -n -e 's/ functions..: [0-9]*.[0-9]% ([0-9]* of \([0-9]*\) functions)$/\1/p') - -LINES_PERCENT=$((1000*$LINES_TESTED/$LINES_TOTAL)) -LINES_PERCENT="$(($LINES_PERCENT/10)).$(($LINES_PERCENT-($LINES_PERCENT/10)*10))" - -FUNCS_PERCENT=$((1000*$FUNCS_TESTED/$FUNCS_TOTAL)) -FUNCS_PERCENT="$(($FUNCS_PERCENT/10)).$(($FUNCS_PERCENT-($FUNCS_PERCENT/10)*10))" - -echo "Lines Tested : $LINES_TESTED of $LINES_TOTAL $LINES_PERCENT%" -echo "Functions Tested : $FUNCS_TESTED of $FUNCS_TOTAL $FUNCS_PERCENT%" -echo - - -rm unit-test-$TEST_OUTPUT -rm cov-$TEST_OUTPUT - -cd .. - -make clean - -if [ -f "$CONFIG_BAK" ]; then - mv "$CONFIG_BAK" "$CONFIG_H" -fi diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-generated-files.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-generated-files.sh deleted file mode 100644 index f41e465c..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-generated-files.sh +++ /dev/null @@ -1,70 +0,0 @@ -#! /usr/bin/env sh - -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2018, ARM Limited, All Rights Reserved -# -# Purpose -# -# Check if generated files are up-to-date. - -set -eu - -if [ -d library -a -d include -a -d tests ]; then :; else - echo "Must be run from mbed TLS root" >&2 - exit 1 -fi - -check() -{ - SCRIPT=$1 - TO_CHECK=$2 - PATTERN="" - FILES="" - - if [ -d $TO_CHECK ]; then - for FILE in $TO_CHECK/*; do - FILES="$FILE $FILES" - done - else - FILES=$TO_CHECK - fi - - for FILE in $FILES; do - cp $FILE $FILE.bak - done - - $SCRIPT - - # Compare the script output to the old files and remove backups - for FILE in $FILES; do - if ! diff $FILE $FILE.bak >/dev/null 2>&1; then - echo "'$FILE' was either modified or deleted by '$SCRIPT'" - exit 1 - fi - mv $FILE.bak $FILE - - if [ -d $TO_CHECK ]; then - # Create a grep regular expression that we can check against the - # directory contents to test whether new files have been created - if [ -z $PATTERN ]; then - PATTERN="$(basename $FILE)" - else - PATTERN="$PATTERN\|$(basename $FILE)" - fi - fi - done - - if [ -d $TO_CHECK ]; then - # Check if there are any new files - if ls -1 $TO_CHECK | grep -v "$PATTERN" >/dev/null 2>&1; then - echo "Files were created by '$SCRIPT'" - exit 1 - fi - fi -} - -check scripts/generate_errors.pl library/error.c -check scripts/generate_query_config.pl programs/test/query_config.c -check scripts/generate_features.pl library/version_features.c -check scripts/generate_visualc_files.pl visualc/VS2010 diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-names.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-names.sh deleted file mode 100644 index 925037c3..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-names.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/sh -# -# This file is part of mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2015-2016, ARM Limited, All Rights Reserved -# -# Purpose -# -# This script confirms that the naming of all symbols and identifiers in mbed -# TLS are consistent with the house style and are also self-consistent. -# -set -eu - -if grep --version|head -n1|grep GNU >/dev/null; then :; else - echo "This script requires GNU grep.">&2 - exit 1 -fi - -printf "Analysing source code...\n" - -tests/scripts/list-macros.sh -tests/scripts/list-enum-consts.pl -tests/scripts/list-identifiers.sh -tests/scripts/list-symbols.sh - -FAIL=0 - -printf "\nExported symbols declared in header: " -UNDECLARED=$( diff exported-symbols identifiers | sed -n -e 's/^< //p' ) -if [ "x$UNDECLARED" = "x" ]; then - echo "PASS" -else - echo "FAIL" - echo "$UNDECLARED" - FAIL=1 -fi - -diff macros identifiers | sed -n -e 's/< //p' > actual-macros - -for THING in actual-macros enum-consts; do - printf "Names of $THING: " - test -r $THING - BAD=$( grep -E -v '^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$' $THING || true ) - if [ "x$BAD" = "x" ]; then - echo "PASS" - else - echo "FAIL" - echo "$BAD" - FAIL=1 - fi -done - -for THING in identifiers; do - printf "Names of $THING: " - test -r $THING - BAD=$( grep -E -v '^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$' $THING || true ) - if [ "x$BAD" = "x" ]; then - echo "PASS" - else - echo "FAIL" - echo "$BAD" - FAIL=1 - fi -done - -printf "Likely typos: " -sort -u actual-macros enum-consts > _caps -HEADERS=$( ls include/mbedtls/*.h include/psa/*.h | egrep -v 'compat-1\.3\.h' ) -NL=' -' -sed -n 's/MBED..._[A-Z0-9_]*/\'"$NL"'&\'"$NL"/gp \ - $HEADERS library/*.c \ - | grep MBEDTLS | sort -u > _MBEDTLS_XXX -TYPOS=$( diff _caps _MBEDTLS_XXX | sed -n 's/^> //p' \ - | egrep -v 'XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$' || true ) -rm _MBEDTLS_XXX _caps -if [ "x$TYPOS" = "x" ]; then - echo "PASS" -else - echo "FAIL" - echo "$TYPOS" - FAIL=1 -fi - -printf "\nOverall: " -if [ "$FAIL" -eq 0 ]; then - rm macros actual-macros enum-consts identifiers exported-symbols - echo "PASSED" - exit 0 -else - echo "FAILED" - exit 1 -fi diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-python-files.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-python-files.sh deleted file mode 100644 index 92904182..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/check-python-files.sh +++ /dev/null @@ -1,12 +0,0 @@ -#! /usr/bin/env sh - -# This file is part of Mbed TLS (https://tls.mbed.org) -# -# Copyright (c) 2018, Arm Limited, All Rights Reserved -# -# Purpose: -# -# Run 'pylint' on Python files for programming errors and helps enforcing -# PEP8 coding standards. - -pylint3 -j 2 scripts/*.py tests/scripts/*.py diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/doxygen.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/doxygen.sh deleted file mode 100644 index e7758c9e..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/doxygen.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -# Make sure the doxygen documentation builds without warnings - -# Abort on errors (and uninitiliased variables) -set -eu - -if [ -d library -a -d include -a -d tests ]; then :; else - echo "Must be run from mbed TLS root" >&2 - exit 1 -fi - -if scripts/apidoc_full.sh > doc.out 2>doc.err; then :; else - cat doc.err - echo "FAIL" >&2 - exit 1; -fi - -cat doc.out doc.err | \ - grep -v "warning: ignoring unsupported tag" \ - > doc.filtered - -if egrep "(warning|error):" doc.filtered; then - echo "FAIL" >&2 - exit 1; -fi - -make apidoc_clean -rm -f doc.out doc.err doc.filtered diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/generate-afl-tests.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/generate-afl-tests.sh deleted file mode 100644 index cbc2f590..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/generate-afl-tests.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh - -# This script splits the data test files containing the test cases into -# individual files (one test case per file) suitable for use with afl -# (American Fuzzy Lop). http://lcamtuf.coredump.cx/afl/ -# -# Usage: generate-afl-tests.sh -# - should be the path to one of the test suite files -# such as 'test_suite_mpi.data' - -# Abort on errors -set -e - -if [ -z $1 ] -then - echo " [!] No test file specified" >&2 - echo "Usage: $0 " >&2 - exit 1 -fi - -SRC_FILEPATH=$(dirname $1)/$(basename $1) -TESTSUITE=$(basename $1 .data) - -THIS_DIR=$(basename $PWD) - -if [ -d ../library -a -d ../include -a -d ../tests -a $THIS_DIR == "tests" ]; -then :; -else - echo " [!] Must be run from mbed TLS tests directory" >&2 - exit 1 -fi - -DEST_TESTCASE_DIR=$TESTSUITE-afl-tests -DEST_OUTPUT_DIR=$TESTSUITE-afl-out - -echo " [+] Creating output directories" >&2 - -if [ -e $DEST_OUTPUT_DIR/* ]; -then : - echo " [!] Test output files already exist." >&2 - exit 1 -else - mkdir -p $DEST_OUTPUT_DIR -fi - -if [ -e $DEST_TESTCASE_DIR/* ]; -then : - echo " [!] Test output files already exist." >&2 -else - mkdir -p $DEST_TESTCASE_DIR -fi - -echo " [+] Creating test cases" >&2 -cd $DEST_TESTCASE_DIR - -split -p '^\s*$' ../$SRC_FILEPATH - -for f in *; -do - # Strip out any blank lines (no trim on OS X) - sed '/^\s*$/d' $f >testcase_$f - rm $f -done - -cd .. - -echo " [+] Test cases in $DEST_TESTCASE_DIR" >&2 - diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-identifiers.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-identifiers.sh deleted file mode 100644 index eaf270c7..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-identifiers.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# -# Create a file named identifiers containing identifiers from internal header -# files or all header files, based on --internal flag. -# Outputs the line count of the file to stdout. -# -# Usage: list-identifiers.sh [ -i | --internal ] - -set -eu - -if [ -d include/mbedtls ]; then :; else - echo "$0: must be run from root" >&2 - exit 1 -fi - -INTERNAL="" - -until [ -z "${1-}" ] -do - case "$1" in - -i|--internal) - INTERNAL="1" - ;; - *) - # print error - echo "Unknown argument: '$1'" - exit 1 - ;; - esac - shift -done - -if [ $INTERNAL ] -then - HEADERS=$( ls include/mbedtls/*_internal.h library/*.h | egrep -v 'compat-1\.3\.h|bn_mul' ) -else - HEADERS=$( ls include/mbedtls/*.h include/psa/*.h library/*.h | egrep -v 'compat-1\.3\.h|bn_mul' ) -fi - -rm -f identifiers - -grep '^[^ /#{]' $HEADERS | \ - sed -e 's/^[^:]*://' | \ - egrep -v '^(extern "C"|(typedef )?(struct|enum)( {)?$|};?$)' \ - > _decls - -if true; then -sed -n -e 's/.* \**\([a-zA-Z_][a-zA-Z0-9_]*\)(.*/\1/p' \ - -e 's/.*(\*\(.*\))(.*/\1/p' _decls -grep -v '(' _decls | sed -e 's/\([a-zA-Z0-9_]*\)[;[].*/\1/' -e 's/.* \**//' -fi > _identifiers - -if [ $( wc -l < _identifiers ) -eq $( wc -l < _decls ) ]; then - rm _decls - egrep -v '^(u?int(16|32|64)_t)$' _identifiers | sort > identifiers - rm _identifiers -else - echo "$0: oops, lost some identifiers" 2>&1 - exit 1 -fi - -wc -l identifiers diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-macros.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-macros.sh deleted file mode 100644 index 3fa66f19..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-macros.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -set -eu - -if [ -d include/mbedtls ]; then :; else - echo "$0: must be run from root" >&2 - exit 1 -fi - -HEADERS=$( ls include/mbedtls/*.h include/psa/*.h | egrep -v 'compat-1\.3\.h' ) - -# White-list macros we want to be able to refer to that don't exist in the -# crypto library, useful when referring to macros in Mbed TLS from comments. -WHITELIST='MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS' - -# Generate a list of macros and combine it with the white-listed macros in -# sorted order. -{ sed -n -e 's/.*#define \([a-zA-Z0-9_]*\).*/\1/p' $HEADERS | - egrep -v '^(asm|inline|EMIT|_CRT_SECURE_NO_DEPRECATE)$|^MULADDC_'; - printf '%s\n' $WHITELIST; -} | sort -u > macros - -wc -l macros diff --git a/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-symbols.sh b/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-symbols.sh deleted file mode 100644 index c2587194..00000000 --- a/Middlewares/Third_Party/mbed-crypto/tests/scripts/list-symbols.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -set -eu - -if [ -d include/mbedtls ]; then :; else - echo "$0: must be run from root" >&2 - exit 1 -fi - -if grep -i cmake Makefile >/dev/null; then - echo "$0: not compatible with cmake" >&2 - exit 1 -fi - -cp include/mbedtls/config.h include/mbedtls/config.h.bak -scripts/config.pl full -CFLAGS=-fno-asynchronous-unwind-tables make clean lib >/dev/null 2>&1 -mv include/mbedtls/config.h.bak include/mbedtls/config.h -if uname | grep -F Darwin >/dev/null; then - nm -gUj library/libmbed*.a 2>/dev/null | sed -n -e 's/^_//p' -elif uname | grep -F Linux >/dev/null; then - nm -og library/libmbed*.a | grep -v '^[^ ]*: *U \|^$\|^[^ ]*:$' | sed 's/^[^ ]* . //' -fi | sort > exported-symbols -make clean - -wc -l exported-symbols diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/app_sfu.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/app_sfu.h deleted file mode 100644 index 079ddb03..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/app_sfu.h +++ /dev/null @@ -1,226 +0,0 @@ -/** - ****************************************************************************** - * @file app_sfu.h - * @author MCD Application Team - * @brief This file contains the configuration of SBSFU application. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef APP_SFU_H -#define APP_SFU_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "se_crypto_config.h" - -/* Exported constants --------------------------------------------------------*/ -/** - * Use this define to choose the type of Firmware Image Programming you want to use. - * This version supports only 2 modes: - * - * SFU_ENCRYPTED_IMAGE: Encrypted Firmware Image - * The image is received in encrypted format. - * The image must be decrypted to be installed: - * this is done according to the selected crypto scheme, - * see @ref SECBOOT_CRYPTO_SCHEME in the SE_CoreBin part. - * - * SFU_CLEAR_IMAGE: Clear Firmware Image - * The image is received in clear format. - * No decrypt operation is needed before installing the image: - * the selected crypto scheme must be compatible with this choice, - * see @ref SECBOOT_CRYPTO_SCHEME in the SE_CoreBin part. - * - * - */ -#if SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 -#define SFU_IMAGE_PROGRAMMING_TYPE SFU_CLEAR_IMAGE -#else -#define SFU_IMAGE_PROGRAMMING_TYPE SFU_ENCRYPTED_IMAGE -#endif /* SECBOOT_CRYPTO_SCHEME */ - -#define SFU_ENCRYPTED_IMAGE (0U) /*!< The Firmware Image to be installed is downloaded in ENCRYPTED format */ -#define SFU_CLEAR_IMAGE (1U) /*!< The Firmware Image to be installed is downloaded in CLEAR format */ - -/*#define SFU_DEBUG_MODE */ /*!< Comment this define to optimize memory footprint (debug mode removed) - No more print on terminal during SBSFU execution */ - -/*#define SFU_VERBOSE_DEBUG_MODE*/ /*!< Uncomment this define when in verbose Debug mode. - this switch activates more debug prints in the console (FSM state info...) */ - - -/*#define SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE*/ /*!< You may uncomment this define when running development tests. - When this switch is activated, the FWIMG part of SB_SFU will - block when an abnormal error is encountered */ - -#if defined(SFU_VERBOSE_DEBUG_MODE) && !defined(SFU_DEBUG_MODE) -#error You cannot activate SFU_VERBOSE_DEBUG_MODE without activating SFU_DEBUG_MODE too. -#endif /* SFU_VERBOSE_DEBUG_MODE && !SFU_DEBUG_MODE */ - -#if defined(SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE) && !defined(SFU_DEBUG_MODE) -#error SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is meant to be used in DEBUG mode -#endif /* SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE && !SFU_DEBUG_MODE */ - -/*#define SFU_TEST_PROTECTION*/ /*!< Auto-test of protections : WRP, PCROP, MPU, FWALL. - Automatically executed @startup */ -#if defined(SFU_TEST_PROTECTION) -#undef SFU_DEBUG_MODE /*!< Remove definition to optimize memory footprint (debug mode removed) */ -#endif /* SFU_TEST_PROTECTION */ - -/** - * SB_SFU status LED. - * The constants below define the LED to be used and the LED blinking frequency to identify some situations. - * This is useful when no log is enabled. - * - * \li The LED blinks every see @ref SFU_COM_YMODEM_DOWNLOAD_TIMEOUT seconds when a local download is waited. - * \li For the other situations, please check the other defines below. - */ -#define SFU_STATUS_LED (LED_GREEN) /*!< LED to be used to provide the SB_SFU status to the end-user */ -#define SFU_STOP_NO_FW_BLINK_DELAY (100U) /*!< Blinks every 100ms when no valid firmware is available and the local - loader feature is disabled - see @ref SECBOOT_USE_LOCAL_LOADER */ -#define SFU_INCORRECT_OB_BLINK_DELAY (250U) /*!< Blinks every 250ms when an Option Bytes issue is detected */ - - -/** - * Optional Features Software Configuration - */ -#if !defined(SFU_TEST_PROTECTION) -#define SECBOOT_LOADER SECBOOT_USE_LOCAL_LOADER /*!< Loader selection inside SBSFU : local/standalone/none */ -#else -#define SECBOOT_LOADER SECBOOT_USE_NO_LOADER /*!< No loader usage forced when SFU_TEST_PROTECTION is set */ -#endif /* SFU_TEST_PROTECTION */ - -#define SECBOOT_USE_LOCAL_LOADER (1U) /*!< local loader feature integrated into SBSFU (YMODEM over UART) */ -#define SECBOOT_USE_STANDALONE_LOADER (2U) /*!< standalone loader : see specific loader project */ -#define SECBOOT_USE_NO_LOADER (3U) /*!< no loader capability at SBSFU stage */ - -/* Uncomment the define below if you want to use minicom with Linux */ -/* #define MINICOM_YMODEM */ /*!< YMODEM protocol handled by MINICOM (Linux): 128 bytes packets */ - -#if defined(MINICOM_YMODEM) -/* Minicom does not accept the debug prints during the YMODEM session */ -#undef SFU_VERBOSE_DEBUG_MODE -#endif /* MINICOM_YMODEM */ - - -/* Multi-images configuration : - - Max : 3 Active images and 3 Download area - - Not necessary same configuration between SFU_NB_MAX_ACTIVE_IMAGE and SFU_NB_MAX_DWL_AREA - - Active slot identified with SFU magic (1,2,3) information from header - - Do not forget to add keys for each image in SE_Corebin/Binary folder - - Master slot : image started in priority if valid - - FW image valide all feature authorized from master slot -*/ -#define SFU_NB_MAX_ACTIVE_IMAGE 1U /*!< 1 active image managed */ -#define SFU_NB_MAX_DWL_AREA 1U /*!< 1 dwl area managed */ -#define MASTER_SLOT SLOT_ACTIVE_1 /*!< SLOT_ACTIVE_1 identified as master slot */ - -/* The define below allows disabling all security IPs at once. - * - * Enabled: all security IPs (WRP, watchdog...) are disabled. - * Disabled: the security IPs can be used (if their specific compiler switches are enabled too). - * - */ - -#define SECBOOT_DISABLE_SECURITY_IPS /*!< Disable all security IPs at once when activated */ - - -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) - -/* Uncomment the following defines when in Release mode. - In debug mode it can be better to disable some of the following protection - for a better Debug experience (WRP, RDP, IWDG, DAP, etc.) */ - -#define SFU_WRP_PROTECT_ENABLE -#define SFU_RDP_PROTECT_ENABLE -/*#define SFU_TAMPER_PROTECT_ENABLE */ /*!< WARNING : Tamper protection deactivated. As the tamper tamper pin is - neither connected to GND nor to 5V (floating level), there are too many - spurious tamper event detected */ -#define SFU_DAP_PROTECT_ENABLE /*!< WARNING: Be Careful if enabling this protection. Debugger will be disconnected. - It might be difficult to reconnect the Debugger.*/ -#define SFU_DMA_PROTECT_ENABLE -#define SFU_IWDG_PROTECT_ENABLE /*!< WARNING: - 1. Be Careful if enabling this protection. IWDG will be active also after - switching to UserApp: a refresh is needed. - 2. The IWDG reload in the SB_SFU code will have to be tuned depending on your - platform (flash size...)*/ -#define SFU_MPU_PROTECT_ENABLE /*!< MPU protection: - Enables/Disables the MPU protection. - If Secure Engine isolation is ensured by MPU (see SFU_ISOLATE_SE_WITH_MPU in - SE_CoreBin\Inc\se_low_level.h), then this switch also enables/disables it, in - addition to the overall MPU protection. */ -#define SFU_MPU_USERAPP_ACTIVATION /*!< MPU protection during UserApp execution : Only active slot(s) considered as an - executable area */ - - -/*#define SFU_FINAL_SECURE_LOCK_ENABLE */ /*!< WARNING: Should be enabled at the end of product development and test - steps. - When enabling this lock, Static protections cannot be modified any more - and Debug is finally disabled. */ - -#if defined(SFU_FINAL_SECURE_LOCK_ENABLE) -#define SFU_PROTECT_RDP_LEVEL (OB_RDP_LEVEL_2) /*!< RDP level2 for product on the field. Final OB lock, Debug - completely disabled, OB update no more possible */ - - -#else -#define SFU_PROTECT_RDP_LEVEL (OB_RDP_LEVEL_1) /*!< RDP level is set as 1 for debugging purposes. A product on the - field should set it as Level2 */ -#endif /* SFU_FINAL_SECURE_LOCK_ENABLE */ - -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ - -/** - * The define below (SECBOOT_OB_DEV_MODE) determines if the OPTION BYTES should be handled in Development mode or not. - * This define is taken into account only if RDP level 2 is not set. - * If RDP level 2 is set no modification can be done anyway. - * - * Enabled: Option Bytes Development Mode enabled. - * SB_SFU uses a "check and apply" strategy when checking the Option Bytes configuration. - * If an OB is not set though it should be then this setting is automatically corrected. - * This applies only as long as RDP level 2 is not set. - * - * Disabled: Option Bytes Development Mode disabled. - * In this mode the Option Bytes are supposed to be already configured properly when the software starts for - the first time. - * SB_SFU checks the Option Bytes configuration but does not correct it. - * If a problem is detected an error message is reported and the execution stops. - */ -#define SECBOOT_OB_DEV_MODE - - -#define SFU_IWDG_TIMEOUT ((uint32_t)15) /*!< IWDG timeout in seconds (the max. value that can be set here depends on - the prescaler settings: IWDG_PRESCALER_XXX. ) */ - - -/** - * Application Configuration - * - */ -#define SFU_FW_VERSION_START_NUM (1U) /*!< The very first version number a Firmware can have - You can also define an upper bound here if you plan to use it */ - -#define SFU_FW_VERSION_INIT_NUM (1U) /*!< The version number accepted when the header is not valid (either because - no FW installed or due to an attack attempt). Could be different from - SFU_FW_VERSION_START_NUM */ -#ifdef __cplusplus -} -#endif - -#endif /* APP_SFU_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_boot.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_boot.c deleted file mode 100644 index 7c0f1caa..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_boot.c +++ /dev/null @@ -1,1761 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_boot.c - * @author MCD Application Team - * @brief SFU BOOT module - * This file provides firmware functions to manage the following - * functionalities of the Secure Boot: - * + Initialization and de-initialization functions - * + Secure Boot Control functions - * + Secure Boot State functions - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#define SFU_BOOT_C - -/* Includes ------------------------------------------------------------------*/ -#include "string.h" -#include "sfu_boot.h" -#include "sfu_loader.h" -#include "sfu_low_level_security.h" -#include "sfu_low_level_flash_int.h" -#include "sfu_low_level.h" -#include "sfu_fsm_states.h" -#include "sfu_error.h" -#include "stm32wlxx_it.h" /* required for the HAL Cube callbacks */ - -/* - * The sfu_com init is provided by the sfu_com_trace module by default. - * If not, then it is taken from the sfu_com_loader module. - */ -#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) -#include "sfu_trace.h" -#else -#include "sfu_trace.h" /* needed anyhow even if the defines will be empty */ -#include "sfu_com_loader.h" /* needed only for the COM init/de-init */ -#endif /* SFU_DEBUG_MODE || SFU_TEST_PROTECTION */ -#include "se_def.h" -#include "se_bootinfo.h" -#include "se_interface_bootloader.h" /* sfu_boot is the bootloader core part */ -#include "sfu_new_image.h" /* the local loader is a kind of "application" running in SB_SFU so it needs the - services to install a FW image */ -#include "sfu_fwimg_services.h" /* sfu_boot uses the services of the FWIMG module */ -#include "sfu_test.h" /* auto tests */ -#include "sfu_fwimg_internal.h" - -#ifdef KMS_ENABLED -#include "tkms.h" -#include "sfu_kms.h" -#endif /* KMS_ENABLED */ - -/* Private typedef -----------------------------------------------------------*/ -typedef struct -{ - SFU_BOOT_StateMachineTypeDef PrevState; /*!< The previous state of the State Machine */ - SFU_BOOT_StateMachineTypeDef CurrState; /*!< The current state of the State Machine */ -} SFU_BOOT_StateMachineContextTypeDef; /*!< Specifies a structure containing the State Machine context - information using during the SM evolution. */ - -/* Private defines -----------------------------------------------------------*/ -#define EXEC_ID_SECURE_BOOT 0U /*!< ID for Secure Boot */ -#define EXEC_ID_USER_APP 1U /*!< ID for User App */ -#define IS_VALID_EXEC_ID(EXEC_ID) (((EXEC_ID) == EXEC_ID_SECURE_BOOT) || \ - ((EXEC_ID) == EXEC_ID_USER_APP)) /*!< Check for valid ID */ - -#define RESERVED_VALUE (0xFEU) /*!< Reserved value. The reserved field used inside the LastExecStatus of the BootInfo is - maintained for future customization/expansion of the field itself */ - -#define SFU_STATE_INITIAL SFU_STATE_CHECK_STATUS_ON_RESET /*!< Define the initial state*/ - -/* Private macros ------------------------------------------------------------*/ -#define SFU_SET_SM_IF_CURR_STATE(Status, SM_STATE_OK, SM_STATE_FAILURE) \ - do{ \ - m_StateMachineContext.PrevState = m_StateMachineContext.CurrState; \ - if (Status == SFU_SUCCESS){ \ - m_StateMachineContext.CurrState = SM_STATE_OK; \ - } \ - else { \ - m_StateMachineContext.CurrState = SM_STATE_FAILURE; \ - } \ - }while(0) /*!< Set a State Machine state according to the 'Status' value*/ - - -#define SFU_SET_SM_CURR_STATE(NewState) \ - do{ \ - m_StateMachineContext.PrevState = m_StateMachineContext.CurrState; \ - m_StateMachineContext.CurrState = NewState; \ - }while(0) /*!< Set a State Machine state*/ - - -#define SFU_GET_LAST_EXEC_STATE(STATUS) (((STATUS)>>8U) & 0xFFU) /*!< Get last State Machine state*/ -#define SFU_GET_LAST_EXEC_IMAGE_ID(STATUS) (((STATUS)>>16U) & 0xFFU) /*!< Get image ID*/ -#define SFU_GET_LAST_EXEC_ID(STATUS) (((STATUS)>>24U) & 0xFFU) /*!< Get Execution ID*/ - -/* Private variables ---------------------------------------------------------*/ -/*!< Static member variables representing the StateMachine context used during the StateMachine evolution. */ -static __IO SFU_BOOT_StateMachineContextTypeDef m_StateMachineContext = {SFU_STATE_INITIAL, - SFU_STATE_INITIAL - }; - -/*!< Static member variables identifyng the slots to be processed by secure firmware update . */ -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -static uint32_t m_DwlSlotToInstall = SLOT_INACTIVE; -#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ -static uint32_t m_ActiveSlotToExecute = SLOT_INACTIVE; - -/* Global variables ----------------------------------------------------------*/ -/** - * This variable indicates if at boot-up the FW presence check has already been performed or not: - * \li It is reset when the FW status has already been checked once and no FW is present - * \li (see @ref SFU_BOOT_SM_CheckUserFwStatus) - * \li It is used to display some messages only once in the teraterm console - * \li It is used to determine if the user button must be pressed before waiting for a local download to start - * \li This is used at LocalDownload and CheckUserFwStatus stages. - */ -uint8_t initialDeviceStatusCheck; - -/** - * Flow control initial values. - * - Security protections flow (static + dynamic) - * - Crypto operations flow (authentication, integrity) - */ -uint32_t uFlowProtectValue = FLOW_CTRL_INIT_VALUE; -uint32_t uFlowCryptoValue = FLOW_CTRL_INIT_VALUE; - -/* Private function prototypes -----------------------------------------------*/ -static SFU_ErrorStatus SFU_BOOT_Init(void); -static SFU_ErrorStatus SFU_BOOT_DeInit(void); -static void SFU_BOOT_BspConfiguration(void); -static SFU_ErrorStatus SFU_BOOT_SM_Run(void); -static void SFU_BOOT_SM_CheckStatusOnReset(void); -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -static void SFU_BOOT_SM_CheckNewFwToDownload(void); -static void SFU_BOOT_SM_DownloadNewUserFw(void); -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ -#ifdef KMS_ENABLED -static void SFU_BOOT_SM_CheckKMSBlobToInstall(void); -static void SFU_BOOT_SM_InstallKMSBlob(void); -#endif /* KMS_ENABLED */ -static void SFU_BOOT_SM_CheckUserFwStatus(void); -static void SFU_BOOT_SM_VerifyUserFwSignature(void); -static void SFU_BOOT_SM_ExecuteUserFw(void); -static void SFU_BOOT_SM_HandleCriticalFailure(void); -static void SFU_BOOT_SM_RebootStateMachine(void); -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -static SFU_ErrorStatus SFU_BOOT_LaunchStandaloneLoader(void); -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ -static SFU_ErrorStatus SFU_BOOT_SystemSecurity_Config(void); -static SFU_ErrorStatus SFU_BOOT_CheckApplySecurityProtections(void); -static SFU_ErrorStatus SFU_BOOT_SecuritySafetyCheck(void); -static SFU_ErrorStatus SFU_BOOT_SetLastExecStatus(uint8_t uExecID, uint8_t uLastExecState); -static SFU_ErrorStatus SFU_BOOT_ManageLastExecStatus(uint32_t uLastExecStatus); -static SFU_ErrorStatus SFU_BOOT_ManageResetSources(void); - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief This function starts the secure boot service and returns only if a configuration issue occurs. - * In the nominal case, the bootloader service runs until the user application is launched. - * When no valid user application can be run (after installing a new image or not), - * if the local loader feature is not enabled then the execution stops, - * otherwise a local download will be awaited. - * If the state machine encounters a major issue then a reboot is triggered. - * @param None. - * @note Please note that this service initializes all the required sub-services and rely on them to perform its tasks. - * @note Constraints - * 1. The system initialization must be completed (HAL, clocks, peripherals...) before calling this function. - * 2. This function also takes care of BSP initialization after enabling the secure mode. - * The BSP init code can be added in @ref SFU_BOOT_BspConfiguration(). - * 3. No other entity should handle the initialization of the Secure Engine. - * 4. The other SB_SFU services should NOT be configured by other entities if this service is used (the previous - * configurations will be overwritten). - * 5. The other SB_SFU services should NOT be used by any other entity if this service is running. - * 6. When returning from this function a reboot should be triggered (NVIC_SystemReset) after processing the - * error cause. - * 7. The caller must be prepared to never get the hand back after calling this function (jumping in user - * application by default or entering local loader state if local loader is enabled or rebooting to install a - * new image). - * @note Settings are handled at compilation time: - * 1. See compiler switches in main.h for secure IPs settings - * 2. The trace system is configured in the sfu_trace.h file - * @retval SFU_BOOT_InitErrorTypeDef error code as the function returns only if a critical failure occurs at init - * stage. - */ -SFU_BOOT_InitErrorTypeDef SFU_BOOT_RunSecureBootService() -{ - SFU_BOOT_InitErrorTypeDef e_ret_code = SFU_BOOT_INIT_ERROR; - - /* - * initialize Secure Engine variable as secure Engine is managed as a completely separate binary - not - * "automatically" managed by SBSFU compiler command - */ - if (SE_Startup() == SE_SUCCESS) - { - /* Security Configuration */ - if (SFU_BOOT_SystemSecurity_Config() == SFU_SUCCESS) - { - /* Board BSP Configuration */ - SFU_BOOT_BspConfiguration(); - - /* Configure the Secure Boot and start the State machine */ - if (SFU_BOOT_Init() == SFU_SUCCESS) - { - /* Start the Secure Boot State Machine */ - (void) SFU_BOOT_SM_Run(); - } - else - { - /* failure when initializing the secure boot service */ - e_ret_code = SFU_BOOT_INIT_FAIL; - } - } - else - { - /* failure when configuring the security IPs */ - e_ret_code = SFU_BOOT_SECIPS_CFG_FAIL; - } - } - else - { - /* failure at secure engine initialization stage */ - e_ret_code = SFU_BOOT_SECENG_INIT_FAIL; - } - - /* - * This point should not be reached unless a critical init failure occurred - * Return the error code - */ - return (e_ret_code); -} - -/** - * @brief Force System Reboot - * @param None - * @retval None - */ -void SFU_BOOT_ForceReboot(void) -{ - /* - * WARNING: The follow TRACEs are for debug only. This function could be called - * inside an IRQ so the below printf could not be executed or could generate a fault! - */ - TRACE("\r\n========= End of Execution =========="); - TRACE("\r\n\r\n\r\n"); - - /* This is the last operation executed. Force a System Reset. */ - NVIC_SystemReset(); -} - -/** - * @brief Initialize the Secure Boot State machine. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_Init(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status; - - /* - * We start the execution at boot-up (display all messages in teraterm console, check the trigger to force a local - * download) - */ - initialDeviceStatusCheck = 1U; - - /* Call the Hardware Abstraction Layer Init implemented for the specific MCU */ - if (SFU_LL_Init() != SFU_SUCCESS) - { - return SFU_ERROR; - } - - /* Flash interface initialization */ - if (SFU_LL_FLASH_Init() != SFU_SUCCESS) - { - return SFU_ERROR; - } - - /* The COM modules is required only if the trace or the local download is enabled */ -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) - /* Call the COM module Init (already handled in SFU_BOOT_SystemSecurity_Config) */ - if (SFU_COM_Init() != SFU_SUCCESS) - { - return SFU_ERROR; - } -#endif /* SECBOOT_USE_LOCAL_LOADER || SFU_DEBUG_MODE || SFU_TEST_PROTECTION*/ - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - /* Call the SFU_LOADER module Init */ - if (SFU_LOADER_Init() != SFU_SUCCESS) - { - return SFU_ERROR; - } -#endif /* SECBOOT_USE_LOCAL_LOADER */ - - /* Call the Exception module Init */ - if (SFU_EXCPT_Init() != SFU_SUCCESS) - { - return SFU_ERROR; - } - - /* Call the image handling Init */ - if (SFU_IMG_InitImageHandling() != SFU_IMG_INIT_OK) - { - return SFU_ERROR; - } /* else continue */ - -#ifdef SFU_TEST_PROTECTION - SFU_TEST_Init(); -#endif /* SFU_TEST_PROTECTION */ - - TRACE("\r\n\r\n"); - TRACE("\r\n======================================================================"); - TRACE("\r\n= (C) COPYRIGHT 2017 STMicroelectronics ="); - TRACE("\r\n= ="); - TRACE("\r\n= Secure Boot and Secure Firmware Update ="); - TRACE("\r\n======================================================================"); - TRACE("\r\n\r\n"); - - /* Initialize the Secure Engine that will be used for all the most critical operations */ - if (SE_Init(&e_se_status, SystemCoreClock) != SE_SUCCESS) - { - TRACE("\r\n= [SBOOT] SECURE ENGINE INITIALIZATION CRITICAL FAILURE!"); - } - else - { - /* Check the Secure Engine Status in order to get more information */ - if (e_se_status == SE_BOOT_INFO_ERR_FACTORY_RESET) - { - TRACE("\r\n= [SBOOT] STATE: WARNING: SECURE ENGINE INITIALIZATION WITH FACTORY DEFAULT VALUES!"); - /* Please add your custom action here */ - /* ... */ - } - else - { - e_ret_status = SFU_SUCCESS; - TRACE("\r\n= [SBOOT] SECURE ENGINE INITIALIZATION SUCCESSFUL"); - } - /* - * The BootInfo consecutive boot on error counter will be handled in SFU_BOOT_ManageResetSources() to decide if it - * is incremented or reset. - * This counter is used to count the number of consecutive resets triggered by an error (in the User Application or - * in SB_SFU when dealing with the user application management). - * So this counter is reset as soon as a normal power off/power on boot is performed. - */ - } - - return e_ret_status; -} - -/** - * @brief DeInitialize the Secure Boot State machine. - * @param None - * @note Please note that in this example the de-init function is used only once to avoid a compiler warning. - * The bootloader can terminate: - * 1. with an init failure : no de-init needed - * 2. with a critical failure leading to a reboot: no de-init needed as long as no persistent info is stored - * by this function. - * 3. when launching the user app: de-init may be called here if required as long as it does not disengage the - * required security mechanisms. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_DeInit(void) -{ - if (SFU_EXCPT_DeInit() != SFU_SUCCESS) - { - return SFU_ERROR; - } - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - if (SFU_LOADER_DeInit() != SFU_SUCCESS) - { - return SFU_ERROR; - } -#endif /* SECBOOT_USE_LOCAL_LOADER */ - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) - if (SFU_COM_DeInit() != SFU_SUCCESS) - { - return SFU_ERROR; - } -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) */ - - if (SFU_LL_DeInit() != SFU_SUCCESS) - { - return SFU_ERROR; - } - - return SFU_SUCCESS; -} - -/** - * @brief BSP Initialization. - * Called when the secure mode is enabled. - * @note The BSP configuration should be handled only in this function. - * @param None - * @retval None - */ -static void SFU_BOOT_BspConfiguration() -{ - /* LED Init*/ - (void) BSP_LED_Init(SFU_STATUS_LED); - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - /* User Button */ - BUTTON_INIT(); -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ -} - -/** - * @brief Execute the Secure Boot state machine. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_SM_Run(void) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - void (*fnStateMachineFunction)(void); - static void (* fnStateMachineTable[])(void) = {SFU_BOOT_SM_CheckStatusOnReset, -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - SFU_BOOT_SM_CheckNewFwToDownload, - SFU_BOOT_SM_DownloadNewUserFw, -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ -#ifdef KMS_ENABLED - SFU_BOOT_SM_CheckKMSBlobToInstall, - SFU_BOOT_SM_InstallKMSBlob, -#endif /* KMS_ENABLED */ - SFU_BOOT_SM_CheckUserFwStatus, - SFU_BOOT_SM_VerifyUserFwSignature, - SFU_BOOT_SM_ExecuteUserFw, - SFU_BOOT_SM_HandleCriticalFailure, - SFU_BOOT_SM_RebootStateMachine - }; - - /* Start the State Machine loop/evolution */ - while (e_ret_status == SFU_SUCCESS) - { - /* Always execute a security/safety check before moving to the next state */ - if (SFU_BOOT_SecuritySafetyCheck() == SFU_SUCCESS) - { - /* - * Except for the 1st state, used to check the last saved execution status, - * let's save the current Execution Status in order to be retrieved and analyzed - * in case a reboot will be triggered by an error, bug, power-off, Hw reset, etc. - */ - if (m_StateMachineContext.CurrState != SFU_STATE_CHECK_STATUS_ON_RESET) - { - (void) SFU_BOOT_SetLastExecStatus(EXEC_ID_SECURE_BOOT, (uint8_t)m_StateMachineContext.CurrState); - } - - /* Get the right StateMachine function according to the current state */ - fnStateMachineFunction = fnStateMachineTable[(uint8_t)m_StateMachineContext.CurrState]; - - /* Call the State Machine function associated to the current state */ - fnStateMachineFunction(); - } - else - { - e_ret_status = SFU_ERROR; - } - } - - /* If the State Machine cannot evolve anymore, reboot is the only option */ - - /* Set the error before forcing a reboot */ - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_UNKNOWN); - - /* This is the last operation executed. Force a System Reset */ - SFU_BOOT_ForceReboot(); - - return e_ret_status; -} - -/** @brief Check the Reset status in order to understand the last cause of Reset - * @param None - * @note This function must set the next State Machine State - * @retval None - */ -static void SFU_BOOT_SM_CheckStatusOnReset(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status; - SE_BootInfoTypeDef x_boot_info; - uint32_t u_last_exec_status; - - TRACE("\r\n= [SBOOT] STATE: CHECK STATUS ON RESET"); - - /* First of all, locally get the last execution status we'll work on, before setting the new state */ - if (SE_INFO_ReadBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - u_last_exec_status = x_boot_info.LastExecStatus; - /* - * Try to save here the current Execution Status in order to be retrieved and analyzed in case a reboot will be - * triggered by an error, bug, power-off, Hw reset, etc. - */ - - if (SFU_BOOT_SetLastExecStatus(EXEC_ID_SECURE_BOOT, (uint8_t)m_StateMachineContext.CurrState) == SFU_SUCCESS) - { - /* Check the wakeup sources */ - if (SFU_BOOT_ManageResetSources() == SFU_SUCCESS) - { - /* Check the last execution status and take the opportune actions */ - if (SFU_BOOT_ManageLastExecStatus(u_last_exec_status) == SFU_SUCCESS) - { - if (SE_INFO_ReadBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - e_ret_status = SFU_SUCCESS; - } /* else SE_INFO_ReadBootInfo fails: go forward as we end up with a critical failure anyway */ - } /* else SFU_BOOT_ManageLastExecStatus fails: go forward as we end up with a critical failure anyway */ - } /* else SFU_BOOT_ManageResetSources fails: go forward as we end up with a critical failure anyway */ - } /* else SFU_BOOT_SetLastExecStatus fails: go forward as we end up with a critical failure anyway */ - } /* else SE_INFO_ReadBootInfo fails: go forward as we end up with a critical failure anyway */ - - - /* Set the next State Machine state according to the success of the failure of e_ret_status */ -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - /* When the local loader feature is supported we need to check if a local download is requested */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD, SFU_STATE_HANDLE_CRITICAL_FAILURE); -#else -#ifdef KMS_ENABLED - /* When the local loader feature is disabled go directly to the check of the KMS blob presence */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_CHECK_KMS_BLOB_TO_INSTALL, SFU_STATE_HANDLE_CRITICAL_FAILURE); -#else - /* When the local loader feature is disabled go directly to the check of the FW status */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_VERIFY_USER_FW_STATUS, SFU_STATE_HANDLE_CRITICAL_FAILURE); -#endif /* KMS_ENABLED */ -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ -} - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -/** - * @brief Check if a new UserApp firmware is available for downloading. - * When entering this state from SFU_STATE_CHECK_STATUS_ON_RESET (initialDeviceStatusCheck=1) it is required - * to press the user button to force the local download. - * When entering this state from SFU_STATE_VERIFY_USER_FW_STATUS the local download is awaited automatically - * (because there is no other action to do). - * @param None - * @note This function must set the next State Machine State. - * @retval None - */ -static void SFU_BOOT_SM_CheckNewFwToDownload(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -#ifdef SECBOOT_BYPASS_MODE_ENABLED - if ((*(uint32_t *)LOADER_COM_REGION_RAM_START) == STANDALONE_LOADER_BYPASS_REQ) - { - TRACE("\r\n= [SBOOT] STATE: Bypass mode - execution standalone loader"); - e_ret_status = SFU_BOOT_LaunchStandaloneLoader(); - - /* This is unreachable code (dead code) in principle... - At this point we should not be able to reach the following instructions. - If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); - } -#endif /* SECBOOT_BYPASS_MODE_ENABLED */ -#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ - - if (initialDeviceStatusCheck == 1U) - { - /* At boot-up, before checking the FW status, a local download can be forced thanks to the user button */ - TRACE("\r\n= [SBOOT] STATE: CHECK NEW FIRMWARE TO DOWNLOAD"); - if (0U != BUTTON_PUSHED()) - { - /* Download requested */ - e_ret_status = SFU_SUCCESS; - } - } - else - { - /* - * The FW status has already been checked and no FW can be launched: no need to check the trigger, wait for a local - * download to start - */ - e_ret_status = SFU_SUCCESS; - } - -#ifdef KMS_ENABLED - /* Set the next State Machine state according to the success of the failure of e_ret_status */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_DOWNLOAD_NEW_USER_FW, SFU_STATE_CHECK_KMS_BLOB_TO_INSTALL); -#else - /* Set the next State Machine state according to the success of the failure of e_ret_status */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_DOWNLOAD_NEW_USER_FW, SFU_STATE_VERIFY_USER_FW_STATUS); -#endif /* KMS_ENABLED */ - -} -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER)*/ - -#ifdef KMS_ENABLED -/** - * @brief Check if a KMSBlob is waiting for installation. - * This state can be entered only from SFU_STATE_CHECK_STATUS_ON_RESET when the local loader feature is - * disabled. - * This state can be entered only from SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD when the local loader feature is - * enabled. - * In this latter case, - * if a new Firmware download is requested, - * it has priority over the KMS blob installation, - * and the KMS blob installation request will be lost. - * @param None - * @note This function must set the next State Machine State. - * @retval None - */ -static void SFU_BOOT_SM_CheckKMSBlobToInstall(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SFU_KMS_BlobInstallStateTypeDef e_PendingInstallStatus; - - /* At boot-up, before checking the FW status, we must check if a KMS blob installation is pending */ - TRACE("\r\n= [SBOOT] STATE: CHECK KMS BLOB TO INSTALL"); - - /* Check if a Blob Installation is requested or on-going */ - e_PendingInstallStatus = SFU_KMS_CheckPendingBlobInstallation(); - - if (SFU_KMS_NO_BLOBUPDATE != e_PendingInstallStatus) - { - /* Blob installation requested */ - e_ret_status = SFU_SUCCESS; - } - - /* Set the next State Machine state according to the success of the failure of e_ret_status */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_INSTALL_KMS_BLOB, SFU_STATE_VERIFY_USER_FW_STATUS); -} - -/** - * @brief Check if a KMSBlob is waiting for install. - * When entering this state from SFU_STATE_CHECK_STATUS_ON_RESET (initialDeviceStatusCheck=1) it is required - * to press the user button to force the local download. - * When entering this state from SFU_STATE_VERIFY_USER_FW_STATUS the local download is awaited automatically - * (because there is no other action to do). - * @param None - * @note This function must set the next State Machine State. - * @retval None - */ -static void SFU_BOOT_SM_InstallKMSBlob(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint8_t *pBlobHdr; - uint8_t *pBlobInFlash; - CK_RV e_status; - - /* At boot-up, Managing ImportBlob through KMS services. */ - TRACE("\r\n= [SBOOT] STATE: INSTALL KMS BLOB"); - - /* Here we will Launch SE service to take consume the Blob */ - /* When the Service confirms that the Blob is installed, then we can erase the SWAP */ - e_ret_status = SFU_KMS_GetBlobInstallInfo(&pBlobHdr, &pBlobInFlash); - if (e_ret_status != SFU_SUCCESS) - { - TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN RETRIEVING BLOB LOCATION"); - } - else - { - /* Initialize KMS in order to be able to import blob using internal algorithms */ - e_status = C_Initialize(NULL); - if (e_status == CKR_OK) - { - /* we do not take the return value into account as we will not retry the import in case of issue */ - e_status = C_STM_ImportBlob(pBlobHdr, pBlobInFlash); - - if (e_status != CKR_OK) - { - (void)C_Finalize(NULL); - } - else - { - e_status = C_Finalize(NULL); - } - } - - if (e_status != CKR_OK) - { - TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN COMMUNICATING WITH KMS"); - } - - /* In any case, we remove the Blob To Install (regardless of the result) */ - e_ret_status = SFU_KMS_EraseBlob(); - - if (e_ret_status != SFU_SUCCESS) - { - TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN ERASING KMS BLOB"); - } - - /* Display the KMS import result */ - switch (e_status) - { - case CKR_OK: - TRACE("\r\n= [SBOOT] INSTALL KMS: KMS BLOB WELL INSTALLED"); - e_ret_status = SFU_SUCCESS; - break; - - case CKR_SIGNATURE_INVALID: - /* At boot-up, Crypto Error when trying to install KMSBlob. */ - TRACE("\r\n= [SBOOT] INSTALL KMS: BLOB AUTHENT ERROR WHEN INSTALLING KMS BLOB"); - e_ret_status = SFU_ERROR; - break; - - case CKR_DATA_INVALID: - /* At boot-up, Crypto Error when trying to install KMSBlob. */ - TRACE("\r\n= [SBOOT] INSTALL KMS: BLOB FORM ERROR WHEN INSTALLING KMS BLOB"); - e_ret_status = SFU_ERROR; - break; - - case CKR_DEVICE_ERROR: - /* At boot-up, NVM Error when trying to install KMSBlob. */ - TRACE("\r\n= [SBOOT] INSTALL KMS: NVM ERROR WHEN INSTALLING KMS BLOB"); - e_ret_status = SFU_ERROR; - break; - - case CKR_OPERATION_ACTIVE: - /* At boot-up, trying to install KMSBlob while KMS is being use. */ - TRACE("\r\n= [SBOOT] INSTALL KMS: KMS KEYS IN USE WHEN INSTALLING KMS BLOB"); - e_ret_status = SFU_ERROR; - break; - - default: - TRACE("\r\n= [SBOOT] INSTALL KMS: UNKNOWN STATUS"); - e_ret_status = SFU_ERROR; - break; - } - } - - /* Set the next State Machine regardless of the KMS import result */ - SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_STATUS); -} - -#endif /* KMS_ENABLED */ - - -/** - * @brief Check the Status of the Fw Image to work on in order to set the next - * State Machine state accordingly - * @param None - * @note This function must set the next State Machine State - * @retval None - */ -static void SFU_BOOT_SM_CheckUserFwStatus(void) -{ -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - SFU_ErrorStatus e_ret_status = SFU_ERROR; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ - uint32_t i; - - if (initialDeviceStatusCheck == 1U) - { - TRACE("\r\n= [SBOOT] STATE: CHECK USER FW STATUS"); - } - -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - if ((*(uint32_t *)LOADER_COM_REGION_RAM_START) == STANDALONE_LOADER_INSTALL_REQ) - { - /* Whatever the status the decryption can be done only once ==> no interruption allowed */ - (*(uint32_t *)LOADER_COM_REGION_RAM_START) = STANDALONE_LOADER_NO_REQ; - - TRACE("\r\n\t New Fw Encrypted, to be decrypted"); - - /* Check if there is a pending action related to a FW update procedure */ - if (SFU_IMG_CheckPendingInstallation(&m_DwlSlotToInstall) == SFU_IMG_FWIMAGE_TO_INSTALL) - { - /* Start installation */ - e_ret_status = SFU_IMG_TriggerImageInstallation(m_DwlSlotToInstall); - } - - /* Critical failure management if installation failed */ - if (e_ret_status != SFU_SUCCESS) - { - SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); - return; - } - } -#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ - - /* - * No FW image installation pending : - * 1- Priority to MASTER_SLOT : check if a firmware is detected - * 2- No firmware identified : verify other slots and start execution on the last detected firmware - * 3- No active firmware candidate for execution ==> Local download - * - * This strategy can be adapted by removing for example execution of step2 ==> focus only on MASTER_SLOT. - */ - - m_ActiveSlotToExecute = 0U; - - /* 1- Priority to MASTER_SLOT : check if a firmware is detected */ - if (MASTER_SLOT != 0xFFU) - { - if (SFU_SUCCESS == SFU_IMG_DetectFW(MASTER_SLOT)) - { - m_ActiveSlotToExecute = MASTER_SLOT; - TRACE("\r\n\t A FW is detected in the slot SLOT_ACTIVE_%d", m_ActiveSlotToExecute); - SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_SIGNATURE); - } - } - - /* 2- No firmware identified : verify other slots and start execution on the last detected firmware */ - if (m_ActiveSlotToExecute == 0U) - { - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) /* Slot configured ? */ - { - if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) - { - m_ActiveSlotToExecute = SLOT_ACTIVE_1 + i; - TRACE("\r\n\t A FW is detected in the slot SLOT_ACTIVE_%d", m_ActiveSlotToExecute); - SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_SIGNATURE); - } - } - } - } - - /* 3- No active firmware candidate for execution ==> Local download */ - if (m_ActiveSlotToExecute == 0U) - { - /* Control if all active slot are empty */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) /* Slot configured ? */ - { - if (SFU_IMG_VerifyEmptyActiveSlot(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) - { - /* - * We should never reach this code. - * Could come from an attack ==> as an example we invalidate current firmware. - */ - TRACE("\r\n\t Slot SLOT_ACTIVE_%d not empty : erasing ...", SLOT_ACTIVE_1 + i); - (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ - } - } - } - - /* - * No valid FW is present in the active slot - * and there is no FW to be installed in UserApp download area: local download (when possible) - */ - if (initialDeviceStatusCheck == 1U) - { - TRACE("\r\n\t No valid FW found in the active slots nor new FW to be installed"); -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - /* Waiting for a local download is automatic, no trigger required. */ - TRACE("\r\n\t Waiting for the local download to start... "); -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ - initialDeviceStatusCheck = 0U; -#ifdef SFU_TEST_PROTECTION - SFU_TEST_Reset(); -#endif /* SFU_TEST_PROTECTION */ - } -#if defined(SFU_VERBOSE_DEBUG_MODE) - else - { - /* - * No ELSE branch (except for verbose debug), because the FW status is checked only once per boot: - * If a FW is present in the active slot => it is checked then launched. - * If there is a FW to install => the installation procedure starts. - * If no FW is present and no installation is pending: - * - if the local loader feature is enabled we enter the local download state - * - if the local loader feature is disabled, the execution is stopped. - */ - TRACE("Abnormal case: SFU_STATE_VERIFY_USER_FW_STATUS is not supposed to be entered more than once per boot."); - } -#endif /* SFU_VERBOSE_DEBUG_MODE */ -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - SFU_SET_SM_CURR_STATE(SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD); -#else - /* - * When the local loader feature is disabled it is not possible to enter the "check new fw download" state. - * Rebooting automatically or keeping on checking the FW status would not necessarily be better. - * So we end up waiting for the user to reboot (or the IWDG to expire). - */ - TRACE("No valid FW and no local loader: execution stopped.\r\n"); - while (1 == 1) - { - (void) BSP_LED_Toggle(SFU_STATUS_LED); - HAL_Delay(SFU_STOP_NO_FW_BLINK_DELAY); - } -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ - } -} - - -#if SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER -/** - * @brief A new UserApp Fw was available. Start to download it - * @param None - * @note Reset is generated at by standalone loader when FW is downloaded. - * @retval None - */ -static void SFU_BOOT_SM_DownloadNewUserFw(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - TRACE("\r\n= [SBOOT] STATE: DOWNLOAD NEW USER FIRMWARE"); - - /* Jump into standalone loader */ - e_ret_status = SFU_BOOT_LaunchStandaloneLoader(); - - /* This is unreachable code (dead code) in principle... - At this point we should not be able to reach the following instructions. - If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); -} -#elif (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) -/** - * @brief A new UserApp Fw was available. Start to download it - * @param None - * @note This function must set the next State Machine State - * @retval None - */ -static void SFU_BOOT_SM_DownloadNewUserFw(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SFU_LOADER_StatusTypeDef e_ret_status_app = SFU_LOADER_ERR_COM; - uint32_t dwl_slot; - uint32_t active_slot; - uint32_t u_size = 0; - - TRACE("\r\n= [SBOOT] STATE: DOWNLOAD NEW USER FIRMWARE"); - - /* - * Download area will be chosen as following. After header analysis : - * - same DWL slot number as SFU magic number, if the slot is configured. - * As example, we will choose SLOT_DWL_2 for SFU2 magic in the FW header - * - by default : SLOT_DWL_1 - */ - e_ret_status = SFU_LOADER_DownloadNewUserFw(&e_ret_status_app, &dwl_slot, &u_size); - if (e_ret_status == SFU_SUCCESS) - { -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t FwSize=%d | PartialFwSize=%d | PartialFwOffset=%d | %d bytes received", - fw_image_header_validated.FwSize, fw_image_header_validated.PartialFwSize, - fw_image_header_validated.PartialFwOffset, u_size); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - - /* Read header in dwl slot */ - e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &fw_image_header_validated, (uint8_t *) SlotStartAdd[dwl_slot], - sizeof(SE_FwRawHeaderTypeDef)); - } - - if (e_ret_status == SFU_SUCCESS) - { - active_slot = SFU_IMG_GetFwImageSlot(&fw_image_header_validated); - if (SFU_IMG_Validation(active_slot, &fw_image_header_validated) != SFU_SUCCESS) - { - /* CleanUp downloaded image (header preserved, for anti-rollback) */ - (void) SFU_IMG_InvalidateCurrentFirmware(active_slot); - - /* no specific error cause set */ -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Cannot memorize that a new image has been downloaded."); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - } - } - else - { - /* CleanUp downloaded image (header preserved, for anti-rollback) */ - (void) SFU_IMG_InvalidateCurrentFirmware(dwl_slot); - - /* Memorize the specific error cause if any before handling this critical failure */ - switch (e_ret_status_app) - { - case SFU_LOADER_ERR_COM: - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_COM_ERROR); - break; - case SFU_LOADER_ERR_FW_VERSION: - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_INCORRECT_VERSION); - break; - case SFU_LOADER_ERR_FW_LENGTH: - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_FW_TOO_BIG); - break; - case SFU_LOADER_ERR_AUTH_FAILED: - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_HEADER_AUTH_FAILED); - break; - case SFU_LOADER_ERR_FLASH: - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_FLASH_ERROR); - break; - case SFU_LOADER_ERR_CRYPTO: - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_DECRYPT_FAILURE); - break; - default: - /* no specific error cause */ - break; - } - } /* else error with no specific error cause */ - /* Set the next State Machine state according to the success of the failure of e_ret_status */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_REBOOT_STATE_MACHINE, SFU_STATE_HANDLE_CRITICAL_FAILURE); -} -#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ - - -/** - * @brief Verify the UserApp Fw signature before executing it - * @param None - * @note This function must set the next State Machine State - * @retval None - */ -static void SFU_BOOT_SM_VerifyUserFwSignature(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint32_t i; - - TRACE("\r\n= [SBOOT] STATE: VERIFY USER FW SIGNATURE"); - - /* Double security check : - - testing "static protections" twice will avoid basic hardware attack - - flow control reached : dynamic protections checked - - re-execute static then dynamic check - - errors caught by FLOW_CONTROL ==> infinite loop */ - FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); - FLOW_CONTROL_INIT(uFlowProtectValue, FLOW_CTRL_INIT_VALUE); - e_ret_status = SFU_LL_SECU_CheckApplyStaticProtections(); - FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_STATIC_PROTECT); - if (e_ret_status == SFU_SUCCESS) - { - e_ret_status = SFU_LL_SECU_CheckApplyRuntimeProtections(SFU_THIRD_CONFIGURATION); - } - FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); - if (e_ret_status != SFU_SUCCESS) - { - /* - * Due to previous flow control, we should never reach this code : - * Critical failure management if installation failed - */ - SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); - return; - } - - /* - * With the 2 images handling: - * 1. the header signature is verified when installing a new firmware - * 2. the firmware signature is checked when installing a new firmware - * 3. remaining part of active slot is kept "clean" during installation procedure - * So following checks should never fail. - */ - /* Check all active slots configured */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - /* Slot configured ? */ - if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) - { - /* FW installed ? */ - if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) - { - /* Initialize Flow control */ - FLOW_CONTROL_INIT(uFlowCryptoValue, FLOW_CTRL_INIT_VALUE); - - /* Check the header signature */ - e_ret_status = SFU_IMG_VerifyActiveImgMetadata(SLOT_ACTIVE_1 + i); - if (SFU_SUCCESS == e_ret_status) - { - /* Check the FW signature */ - e_ret_status = SFU_IMG_VerifyActiveImg(SLOT_ACTIVE_1 + i); - if (SFU_SUCCESS == e_ret_status) - { - /* Verify that there is no additional code beyond firmware image */ - e_ret_status = SFU_IMG_VerifyActiveSlot(SLOT_ACTIVE_1 + i); - if (SFU_SUCCESS != e_ret_status) - { -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Unexpected code beyond FW image in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - } - } - else - { -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Firmware signature verification failure in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - } - } - else - { -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Header signature verification failure in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - } - /* - * One of the checks fails : - * - Header signature - * - FW signature - * - No malicious code - * ==> Active slot should be invalidated - */ - if (SFU_SUCCESS != e_ret_status) - { - /* - * We should never reach this code. - * Could come from an attack ==> as an example we invalidate current firmware. - */ -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Erasing slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ - } - else - { - /* Verify if authentication and integrity controls performed */ - FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); - } - } - else - { - if (SFU_IMG_VerifyEmptyActiveSlot(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) - { - /* - * We should never reach this code. - * Could come from an attack ==> as an example we invalidate current firmware. - */ -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Slot SLOT_ACTIVE_%d not empty : erasing ...", SLOT_ACTIVE_1 + i); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ - } - } - } - } - - /* Set the next State Machine state according to the success of the failure of e_ret_status */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_EXECUTE_USER_FW, SFU_STATE_HANDLE_CRITICAL_FAILURE); -} - -/** - * @brief Exit from the SB/SFU State Machine and try to execute the UserApp Fw - * @param None - * @note This function must set the next State Machine State - * @retval None - */ -static void SFU_BOOT_SM_ExecuteUserFw(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status = SE_KO; - uint32_t i; - - TRACE("\r\n= [SBOOT] STATE: EXECUTE USER FIRMWARE"); - - /* Reload Watchdog */ - (void) SFU_LL_SECU_IWDG_Refresh(); - - /* Verify if authentication and integrity controls performed at SFU_STATE_VERIFY_USER_FW_SIGNATURE */ - FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); - - /* Double security check for all active slots : - - Control twice the Header signature will avoid basic hardware attack - - Control twice the FW signature will avoid basic hardware attack */ - - /* Check all active slots configured */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - /* Slot configured ? */ - if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) - { - /* FW installed ? */ - if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) - { - /* Initialize Flow control */ - FLOW_CONTROL_INIT(uFlowCryptoValue, FLOW_CTRL_INIT_VALUE); - - /* Check the header signature */ - if (SFU_IMG_VerifyActiveImgMetadata(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) - { - /* Security issue : execution stopped ! */ - SFU_EXCPT_Security_Error(); - } - - /* Check the FW signature */ - if (SFU_IMG_ControlActiveImgTag(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) - { - /* Security issue : execution stopped ! */ - SFU_EXCPT_Security_Error(); - } - -#if defined(ENABLE_IMAGE_STATE_HANDLING) && !defined(SFU_NO_SWAP) - /* Move the state to SELFTEST for the new images */ - if (SFU_IMG_UpdateImageState(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) - { - /* Image state cannot be changed : What to do ? - ==> decision to continue execution */ - TRACE("\r\n= [FWIMG] WARNING: IMAGE STATE CANNOT BE CHANGED!"); - } -#endif /* ENABLE_IMAGE_STATE_HANDLING && !(SFU_NO_SWAP) */ - - /* Verify if authentication and integrity controls performed */ - FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); - } - } - } - - /* - * Try to set the last execution status and continue: we assume the UserApp will start or a failure will be linked to - * the UserApp code so we can change the EXEC_ID now - */ - e_ret_status = SFU_BOOT_SetLastExecStatus(EXEC_ID_USER_APP, (uint8_t)m_StateMachineContext.CurrState); - - /* - * You may decide to implement additional checks before running the Firmware. - * For the time being we launch the FW present in the active slot. - * - * The bootloader must also take care of the security aspects: - * A.configure (if any) the external flash in execution mode with On The Fly DECryption (OTFDEC) - * B.lock the SE services the UserApp is not allowed to call - * C.leave secure boot mode - */ - - /* Configure active slot in execution mode with OTFDEC (if any) : required in case of external flash */ - if (e_ret_status == SFU_SUCCESS) - { - e_ret_status = SFU_LL_FLASH_Config_Exe(m_ActiveSlotToExecute); - } - - if (e_ret_status == SFU_SUCCESS) - { - - /* Lock part of Secure Engine services */ - if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) - { - /* De-initialize the SB_SFU bootloader before launching the UserApp */ - (void)SFU_BOOT_DeInit(); /* the return value is not checked, we will always try launching the UserApp */ - - /* Last flow control : lock service */ - FLOW_CONTROL_STEP(uFlowCryptoValue, FLOW_STEP_LOCK_SERVICE, FLOW_CTRL_LOCK_SERVICE); - - /* This function should not return */ - e_ret_status = SFU_IMG_LaunchActiveImg(m_ActiveSlotToExecute); - - /* This point should not be reached */ -#if defined(SFU_VERBOSE_DEBUG_MODE) - /* We do not memorize any specific error, the FSM state is already providing the info */ - TRACE("\r\n= SFU_IMG_LaunchActiveImg(SLOT_ACTIVE_%d) failure!", m_ActiveSlotToExecute); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - while (1 == 1) - { - ; /* wait for watchdog */ - } - } - else - { - TRACE("\r\n= [FWIMG] SECURE ENGINE CRITICAL FAILURE!"); - - /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_LOCK_SE_SERVICES_ERR); - - /* This is the last operation executed. Force a System Reset */ - SFU_BOOT_ForceReboot(); - } - } - else - { - TRACE("\r\n= [FWIMG] EXTERNAL FLASH CONFIGURATION FAILURE!"); - - /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ - (void)SFU_BOOT_SetLastExecError((uint32_t)SFU_EXCPT_FLASH_ERROR); - - /* This is the last operation executed. Force a System Reset */ - SFU_BOOT_ForceReboot(); - } - - /* This is unreachable code (dead code) in principle... - At this point we should not be able to reach the following instructions. - If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ - SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); -} - -/** - * @brief Manage a Critical Failure occurred during the evolution of the State Machine - * @param None - * @note After a Critical Failure a Reboot will be called. - * @retval None - */ -static void SFU_BOOT_SM_HandleCriticalFailure(void) -{ - TRACE("\r\n= [SBOOT] STATE: HANDLE CRITICAL FAILURE"); - - /* Any Critical Failure will be served and a SystemReset will be triggered */ - SFU_BOOT_StateExceptionHandler(m_StateMachineContext.PrevState); - - /* It's not possible to continue without compromising the stability or the security of the solution. - The State Machine needs to be aborted and a Reset must be triggered */ - SFU_SET_SM_IF_CURR_STATE(SFU_ERROR, SFU_STATE_REBOOT_STATE_MACHINE, SFU_STATE_REBOOT_STATE_MACHINE); -} - -/** - * @brief The state machine is aborted and a Reset is triggered - * @param None - * @note You are in this condition because it's not possible to continue without - compromising the stability or the security of the solution. - * @retval None - */ -static void SFU_BOOT_SM_RebootStateMachine(void) -{ - TRACE("\r\n= [SBOOT] STATE: REBOOT STATE MACHINE"); - - /* - * In case some clean-up must be done before resetting. - * Please note that at the moment this function does not clean-up the RAM used by SB_SFU. - */ - (void)SFU_BOOT_DeInit(); - - /* This is the last operation executed. Force a System Reset */ - SFU_BOOT_ForceReboot(); -} - -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -/** - * @brief Jump into standalone loader - * @param None - * @retval None - */ -static SFU_ErrorStatus SFU_BOOT_LaunchStandaloneLoader(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status = SE_KO; - uint32_t jump_address ; - typedef void (*Function_Pointer)(void); - Function_Pointer p_jump_to_function; - - /* Lock part of Secure Engine services */ - if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) - { - /* Give execution rights to standalone loader */ - e_ret_status = SFU_LL_SECU_SetProtectionMPU_StandaloneLoader(); - } - - if (e_ret_status == SFU_SUCCESS) - { - /* Initialize address to jump */ - jump_address = *(__IO uint32_t *)(((uint32_t)LOADER_REGION_ROM_START + 4)); - p_jump_to_function = (Function_Pointer) jump_address; - - /* Initialize loader's Stack Pointer */ - __set_MSP(*(__IO uint32_t *)(LOADER_REGION_ROM_START)); - - /* Jump into loader */ - p_jump_to_function(); - } - - /* The point below should NOT be reached */ - return e_ret_status; -} -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ - -/** - * @brief Check (and Apply when possible) the security/safety/integrity protections. - * The "Apply" part depends on @ref SECBOOT_OB_DEV_MODE and @ref SFU_PROTECT_RDP_LEVEL. - * @param None - * @note This operation should be done as soon as possible after a reboot. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_CheckApplySecurityProtections(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Apply Static protections involving Option Bytes */ - if (SFU_LL_SECU_CheckApplyStaticProtections() == SFU_SUCCESS) - { - /* Apply runtime protections needed to be enabled after each Reset */ - e_ret_status = SFU_LL_SECU_CheckApplyRuntimeProtections(SFU_INITIAL_CONFIGURATION); - } - - return e_ret_status; -} - -/** - * @brief System security configuration - * @param None - * @note Check and apply the security protections. This has to be done as soon - * as possible after a reset - * @retval None - */ -static SFU_ErrorStatus SFU_BOOT_SystemSecurity_Config(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - /* WARNING: The following CheckApplySecurityProtection function must be called - as soon as possible after a Reset in order to be sure the system is secured - before starting any other operation. The drawback is that the ErrorManagement - is not initialized yet, so in case of failure of this function, there will not be - any error stored into the BootInfo or other visible effects. */ - - /* Very few things are already initialized at this stage. Need additional initialization - to show a message that is added as below only in Debug/Test mode */ -#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) - (void) SFU_COM_Init(); -#endif /* SFU_DEBUG_MODE || SFU_TEST_PROTECTION */ - - if (SFU_BOOT_CheckApplySecurityProtections() != SFU_SUCCESS) - { - /* WARNING: This might be generated by an attempted attack or a bug of your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - TRACE("\r\n= [SBOOT] System Security Check failed! Rebooting..."); - } - else - { - TRACE("\r\n= [SBOOT] System Security Check successfully passed. Starting..."); - e_ret_status = SFU_SUCCESS; - } - - return e_ret_status; -} - -/** - * @brief Periodic verification of applied protection mechanisms, in order to prevent - * a malicious code removing some of the applied security/integrity features. - * The IWDG is also refreshed in this function. - * @param None - * @note This function must be called with a frequency greater than 0.25Hz! - * Otherwise a Reset will occur. Once enabled the IWDG cannot be disabled - * So the User App should continue to refresh the IWDG counter. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_SecuritySafetyCheck(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Refresh the IWDG */ - e_ret_status = SFU_LL_SECU_IWDG_Refresh(); - - - /* Add your code here for customization: - e.g. for additional security or safety periodic check. - ... - ... - */ - return e_ret_status; -} - -/** - * @brief Set the last execution status. For future customization the parameter - * list can be extended with an additional uint8_t, that at the moment is - * stored with a reserved default value. - * @param uExecID: This parameter can be a value of @ref SFU_BOOT_Private_Defines_Execution_Id - * @param uLastExecState: the last SM state to store into the BootInfo structure. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_SetLastExecStatus(uint8_t uExecID, uint8_t uLastExecState) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status; - SE_BootInfoTypeDef x_boot_info; - uint8_t uFwImageIdx = 0U; - - if ((IS_VALID_EXEC_ID(uExecID)) && (IS_SFU_SM_STATE(uLastExecState))) - { - if (SE_INFO_ReadBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - /* Set the last execution status as a 32-bit data */ - x_boot_info.LastExecStatus = RESERVED_VALUE - | ((uint32_t)uLastExecState << 8U) - | ((uint32_t)uFwImageIdx << 16U) - | ((uint32_t)uExecID << 24U); - - /* Update the BootInfo shared area according to the modifications above */ - if (SE_INFO_WriteBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - e_ret_status = SFU_SUCCESS; - } - - } - } - return e_ret_status; -} - -/** - * @brief Manage the the last execution status, and take the right actions accordingly - * @param uLastExecStatus: 32-bit representing the @ref SFU_BOOT_Private_Macros_Execution_Status - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_ManageLastExecStatus(uint32_t uLastExecStatus) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status; - SE_BootInfoTypeDef x_boot_info; - SFU_EXCPT_IdTypeDef u_last_error; - - if (SE_INFO_ReadBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { -#if defined(SFU_VERBOSE_DEBUG_MODE) - /* Show the last execution state */ - TRACE("\r\n\t INFO: Last execution status before Reboot was:"); - if (IS_SFU_SM_STATE(SFU_GET_LAST_EXEC_STATE(uLastExecStatus))) - { - TRACE(m_aStateMachineStrings[SFU_GET_LAST_EXEC_STATE(uLastExecStatus)]); - } - else - { - TRACE("Unknown"); - } -#else - UNUSED(uLastExecStatus); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - - /* Show the last execution error */ - u_last_error = (SFU_EXCPT_IdTypeDef) x_boot_info.LastExecError; - TRACE("\r\n\t INFO: Last execution detected error was: "); - if (IS_SFU_EXCPT(u_last_error)) - { - TRACE((char const *)m_aErrorStrings[u_last_error]); - } - else - { - TRACE("Unknown error."); - u_last_error = SFU_EXCPT_UNKNOWN; - } - - /* Custom handler of the last error detected at reset */ - if ((SFU_EXCPT_IdTypeDef)u_last_error != SFU_EXCPT_NONE) - { - SFU_EXCPT_ResetExceptionHandler((SFU_EXCPT_IdTypeDef)u_last_error); - } - - /* - * It's possible to reset the error at this point (because we are in SFU_STATE_CHECK_STATUS_ON_RESET context so no - * need to memorize the exception further) - */ - x_boot_info.LastExecError = (uint32_t) SFU_EXCPT_NONE; - - /* Update the BootInfo shared area according to the modifications above */ - if (SE_INFO_WriteBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - e_ret_status = SFU_SUCCESS; - } - } - - return e_ret_status; -} - -/** - * @brief Manage the the Reset sources, and if the case store the error for the next steps - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_BOOT_ManageResetSources(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SFU_RESET_IdTypeDef e_wakeup_source_id = SFU_RESET_UNKNOWN; - SFU_EXCPT_IdTypeDef e_exception; - SE_BootInfoTypeDef x_boot_info; /* to retrieve and update the counter of consecutive errors */ - SE_StatusTypeDef e_se_status; - - /* Check the wakeup sources */ - SFU_LL_SECU_GetResetSources(&e_wakeup_source_id); - switch (e_wakeup_source_id) - { - /* - * Please note that the example of reset causes handling below is only a basic example to illustrate the way the - * RCC_CSR flags can be used to do so. - * It is based on the behaviors we consider as normal and abnormal for the SB_SFU and UserApp example projects - * running on a Nucleo HW board. - * Hence this piece of code must systematically be revisited and tuned for the targeted system (software and - * hardware expected behaviors must be assessed to tune this code). - * - * One may use the "uExecID" parameter to determine if the last exec status was in the SB_SFU context or UserApp - * context to implement more clever checks in the reset cause handling below. - */ - - case SFU_RESET_WDG_RESET: - TRACE("\r\n\t WARNING: A Reboot has been triggered by a Watchdog reset!"); - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - /* This event has to be considered as an error to manage */ - e_exception = SFU_EXCPT_WATCHDOG_RESET; - break; - - case SFU_RESET_LOW_POWER: - TRACE("\r\n\t INFO: A Reboot has been triggered by a LowPower reset!"); - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - /* In the current implementation this event is not considered as an error to manage. - But this is strictly related to the final system. If needed to be managed as an error - please add the right error code in the following src code line */ - e_exception = SFU_EXCPT_NONE; - break; - - case SFU_RESET_HW_RESET: - TRACE("\r\n\t INFO: A Reboot has been triggered by a Hardware reset!"); - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - /* In the current implementation this event is not considered as an error to manage. - This is because a Nucleo board offers a RESET button triggering the HW reset. - But this is strictly related to the final system. If needed to be managed as an error - please add the right error code in the following src code line */ - e_exception = SFU_EXCPT_NONE; - break; - - case SFU_RESET_BOR_RESET: - TRACE("\r\n\t INFO: A Reboot has been triggered by a BOR reset!"); - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - /* In the current implementation this event is not considered as an error to manage. - But this is strictly related to the final system. If needed to be managed as an error - please add the right error code in the following src code line */ - e_exception = SFU_EXCPT_NONE; - break; - - case SFU_RESET_SW_RESET: - TRACE("\r\n\t INFO: A Reboot has been triggered by a Software reset!"); - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - /* In the current implementation this event is not considered as an error to manage, - also because a sw reset is generated when the State Machine forces a Reboot. - But this is strictly related to the final system. If needed to be managed as an error - please add the right error code in the following src code line */ - e_exception = SFU_EXCPT_NONE; - break; - - case SFU_RESET_OB_LOADER: - TRACE("\r\n\t WARNING: A Reboot has been triggered by an Option Bytes reload!"); - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - /* In the current implementation this event is not considered as an error to manage, - also because an OptionByte loader is called after applying some of the security protections - (see SFU_CheckApplyStaticProtections). - But this is strictly related to the final system. If needed to be managed as an error - please add the right error code in the following src code line. - Typically we may implement a more clever check where we determine if this OB reset occurred only once because - SB_SFU had to tune the OB initially, or if it occurred again after these initial settings. If so, we could - consider it as an attack. */ - e_exception = SFU_EXCPT_NONE; - break; - - default: - TRACE("\r\n\t WARNING: A Reboot has been triggered by an Unknown reset source!"); - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system, or simply discard it if this is expected. - ... - ... - */ - /* In the current implementation this event is not considered as an error to manage. - But this is strictly related to the final system. If needed to be managed as an error - please add the right error code in the following src code line */ - e_exception = SFU_EXCPT_NONE; - break; - } - - if (SE_INFO_ReadBootInfo(&e_se_status, &x_boot_info) != SE_SUCCESS) - { - /* This is not supposed to occur because ReadBootInfo is already called before SFU_BOOT_ManageResetSources() is - entered... */ - TRACE("\r\n\t BOOT INFO reading Error"); - /* Do nothing more and return an error */ - } - else - { - /* In case an error has been set above, set/overwrite it into the BootInfo */ - if (e_exception != SFU_EXCPT_NONE) - { - /* increment number of consecutive boot errors */ - x_boot_info.ConsecutiveBootOnErrorCounter++; -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Consecutive Boot on error counter ++ "); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - } - else - { - /* - * The reset cause is considered as normal so we reset the counter of consecutive errors - */ - x_boot_info.ConsecutiveBootOnErrorCounter = 0; -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Consecutive Boot on error counter reset "); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - } - - /* Log the consecutive init counter value in the console */ - TRACE("\r\n\t Consecutive Boot on error counter = %d ", x_boot_info.ConsecutiveBootOnErrorCounter); - - /* Update BootInfo structure with consecutive boot counter */ - if (SE_INFO_WriteBootInfo(&e_se_status, &x_boot_info) != SE_SUCCESS) - { - TRACE("\r\n\t BOOT INFO Consecutive Boot on error counter writing error "); - } - else - { - e_ret_status = SFU_SUCCESS; -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n\t Consecutive Boot on error counter updated "); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - } - } - - /* Update the last exec error if needed */ - if (e_exception != SFU_EXCPT_NONE) - { - if (SFU_BOOT_SetLastExecError((uint32_t)e_exception) != SFU_SUCCESS) - { - e_ret_status = SFU_ERROR; - } /* else keep the previous e_ret_status value */ - } /* else: no need to update it */ - - /* Once the reset sources has been managed and a possible error has been set, clear the reset sources */ - SFU_LL_SECU_ClearResetSources(); - - return e_ret_status; -} - -/** - * @brief Implement the Cube_Hal Callback generated on the Tamper IRQ. - * @param None - * @retval None - */ -void SFU_CALLBACK_ANTITAMPER(RTC_HandleTypeDef *hrtc) -{ - UNUSED(hrtc); - SFU_BOOT_IrqExceptionHandler(SFU_EXCPT_TAMPERING_FAULT); -} - -/** - * @brief Implement the Cube_Hal Callback generated on the Memory Fault. - * @note After a Memory Fault could not be possible to execute additional code - * @param None - * @retval None - */ -void SFU_CALLBACK_MEMORYFAULT(void) -{ - SFU_BOOT_IrqExceptionHandler(SFU_EXCPT_MEMORY_FAULT); -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_loader.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_loader.c deleted file mode 100644 index 23111c05..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_loader.c +++ /dev/null @@ -1,544 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_com_loader.c - * @author MCD Application Team - * @brief Secure Firmware Update COM module. - * This file provides set of firmware functions to manage SFU Com - * functionalities for the local loader. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_low_level.h" -#include "sfu_low_level_security.h" -#include "sfu_com_loader.h" -#include "sfu_trace.h" - - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_TEST_PROTECTION) - -/* Private defines -----------------------------------------------------------*/ -#if defined(__ICCARM__) -#define PUTCHAR_PROTOTYPE int putchar(int ch) -#elif defined(__ARMCC_VERSION) -#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) -#elif defined(__GNUC__) -#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) -#endif /* __ICCARM__ */ - -#define SFU_COM_LOADER_TIME_OUT ((uint32_t )0x800U) /*!< COM Transmit and Receive Timeout*/ -#define SFU_COM_LOADER_SERIAL_TIME_OUT ((uint32_t )100U) /*!< Serial PutByte and PutString Timeout*/ - -/* Private macros ------------------------------------------------------------*/ -#define IS_CAP_LETTER(c) (((c) >= (uint8_t) 'A') && ((c) <= (uint8_t) 'F')) -#define IS_LC_LETTER(c) (((c) >= (uint8_t) 'a') && ((c) <= (uint8_t) 'f')) -#define IS_09(c) (((c) >= (uint8_t) '0') && ((c) <= (uint8_t) '9')) -#define ISVALIDHEX(c) (IS_CAP_LETTER(c) || IS_LC_LETTER(c) || IS_09(c)) -#define ISVALIDDEC(c) IS_09(c) -#define CONVERTDEC(c) ((c) - (uint8_t) '0') - -#define CONVERTHEX_ALPHA(c) (IS_CAP_LETTER(c) ? ((c) - (uint8_t) 'A' + 10U) : ((c) - (uint8_t) 'a' + 10U)) -#define CONVERTHEX(c) (IS_09(c) ? ((c) - (uint8_t) '0') : CONVERTHEX_ALPHA(c)) - -/* Private function prototypes -----------------------------------------------*/ -static HAL_StatusTypeDef ReceivePacket(uint8_t *pData, uint32_t *puLength, uint32_t uTimeOut); -static uint32_t Str2Int(uint8_t *pInputStr, uint32_t *pIntNum); - -/* Functions Definition ------------------------------------------------------*/ - -#if !defined(SFU_DEBUG_MODE) && !defined(SFU_TEST_PROTECTION) -/** - * @brief SFU Com Init function. - * @param None. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_COM_Init(void) -{ -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) - setvbuf(stdout, NULL, _IONBF, 0); -#endif /* __GNUC__ */ - return SFU_LL_UART_Init(); -} - -/** - * @brief SFU Com DeInit function. - * @param None. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_COM_DeInit(void) -{ - return SFU_LL_UART_DeInit(); -} - -#endif /* !SFU_DEBUG_MODE && !SFU_TEST_PROTECTION */ - -/** - * @brief Receive a file using the ymodem protocol with SFU_COM_YMODEM_CRC16. - * @param peCOMStatus: SFU_COM_YMODEM_StatusTypeDef result of reception/programming. - * @param puSize: size of received file. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise - */ -SFU_ErrorStatus SFU_COM_YMODEM_Receive(SFU_COM_YMODEM_StatusTypeDef *peCOMStatus, uint32_t *puSize) -{ - uint32_t i; - uint32_t packet_length = 0U; - uint32_t session_done = 0U; - uint32_t file_done; - uint32_t errors = 0U; - uint32_t session_begin = 0U; - uint32_t filesize = 0U; - uint32_t packets_received; - uint8_t *file_ptr; - uint8_t file_size[SFU_COM_YMODEM_FILE_SIZE_LENGTH + 1U]; - uint8_t tmp; - static uint8_t m_aPacketData[SFU_COM_YMODEM_PACKET_1K_SIZE + SFU_COM_YMODEM_PACKET_DATA_INDEX + - SFU_COM_YMODEM_PACKET_TRAILER_SIZE] __attribute__((aligned(4))); - - /* Check the pointers allocation */ - if ((peCOMStatus == NULL) || (puSize == NULL)) - { - return SFU_ERROR; - } - - *peCOMStatus = SFU_COM_YMODEM_OK; - - while ((session_done == 0U) && (*peCOMStatus == SFU_COM_YMODEM_OK)) - { - packets_received = 0U; - file_done = 0U; - while ((file_done == 0U) && (*peCOMStatus == SFU_COM_YMODEM_OK)) - { - switch (ReceivePacket(m_aPacketData, &packet_length, SFU_COM_YMODEM_DOWNLOAD_TIMEOUT)) - { - case HAL_OK: - errors = 0U; - switch (packet_length) - { - case 3U: - /* Startup sequence */ - break; - case 2U: - /* Abort by sender */ - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); - *peCOMStatus = SFU_COM_YMODEM_ABORT; - break; - case 0U: - /* End of transmission */ - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); - *puSize = filesize; - file_done = 1U; - break; - default: - /* Normal packet */ - if (m_aPacketData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX] != (packets_received & 0x000000FFU)) - { - /* No NACK sent for a better synchro with remote : packet will be repeated */ - } - else - { - if (packets_received == 0U) - { - /* File name packet */ - if (m_aPacketData[SFU_COM_YMODEM_PACKET_DATA_INDEX] != 0U) - { - /* File name skipped */ - i = 0U; - file_ptr = m_aPacketData + SFU_COM_YMODEM_PACKET_DATA_INDEX; - while ((*file_ptr != 0U) && (i < SFU_COM_YMODEM_FILE_NAME_LENGTH)) - { - i++; - file_ptr++; - } - /* end of file name ('\0') skipped */ - file_ptr++; - - /* File size extraction */ - i = 0U; - while ((*file_ptr != (uint8_t) ' ') && (i < SFU_COM_YMODEM_FILE_SIZE_LENGTH)) - { - file_size[i] = *file_ptr; - i++; - file_ptr++; - } - file_size[i] = (uint8_t) '\0'; - (void) Str2Int(file_size, &filesize); - - /* Header packet received callback call*/ - if (SFU_COM_YMODEM_HeaderPktRxCpltCallback((uint32_t) filesize) == SFU_SUCCESS) - { - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); - (void) SFU_LL_UART_Flush(); - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CRC16); - } - else - { - /* End session */ - tmp = SFU_COM_YMODEM_CA; - (void) SFU_LL_UART_Transmit(&tmp, 1U, SFU_COM_YMODEM_NAK_TIMEOUT); - (void) SFU_LL_UART_Transmit(&tmp, 1U, SFU_COM_YMODEM_NAK_TIMEOUT); - return SFU_ERROR; - } - } - /* File header packet is empty, end session */ - else - { - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); - file_done = 1U; - session_done = 1U; - break; - } - } - else /* Data packet */ - { - /* Data packet received callback call*/ - if (SFU_COM_YMODEM_DataPktRxCpltCallback(&m_aPacketData[SFU_COM_YMODEM_PACKET_DATA_INDEX], - packet_length) == SFU_SUCCESS) - { - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); - - } - else /* An error occurred while writing to Flash memory */ - { - /* End session */ - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); - *peCOMStatus = SFU_COM_YMODEM_DATA; - } - - } - packets_received ++; - session_begin = 1; - } - break; - } - break; - case HAL_BUSY: /* Abort actually */ - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); - *peCOMStatus = SFU_COM_YMODEM_ABORT; - break; - default: - if (session_begin > 0U) - { - errors ++; - } - if (errors > SFU_COM_YMODEM_MAX_ERRORS) - { - /* Abort communication */ - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); - *peCOMStatus = SFU_COM_YMODEM_ABORT; - } - else - { - (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CRC16); /* Ask for a packet */ -#ifndef MINICOM_YMODEM - /* Minicom does not accept this extra character */ - TRACE("\b."); /* Replace C char by . on display console */ -#endif /* MINICOM_YMODEM */ - /* - * Toggling the LED in case no console is available: the toggling frequency depends on - * SFU_COM_YMODEM_DOWNLOAD_TIMEOUT - */ - (void) BSP_LED_Toggle(SFU_STATUS_LED); - } - break; - } - } - } - /* Make sure the status LED is turned off */ - (void) BSP_LED_Off(SFU_STATUS_LED); - - if (*peCOMStatus == SFU_COM_YMODEM_OK) - { - return SFU_SUCCESS; - } - else - { - return SFU_ERROR; - } -} - -/** - * @brief Transmit a byte to the COM Port. - * @param uParam: The byte to be sent. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_COM_Serial_PutByte(uint8_t uParam) -{ - return SFU_LL_UART_Transmit(&uParam, 1U, SFU_COM_LOADER_SERIAL_TIME_OUT); -} - -/** - * @brief Convert a string to an integer. - * @param pInputStr: The string to be converted. - * @param pIntNum: The integer value. - * @retval 1: Correct - * 0: Error - */ -static uint32_t Str2Int(uint8_t *pInputStr, uint32_t *pIntNum) -{ - uint32_t i = 0U; - uint32_t res = 0U; - uint32_t val = 0U; - uint8_t x; - - if ((pInputStr[0] == (uint8_t)'0') && ((pInputStr[1] == (uint8_t)'x') || (pInputStr[1] == (uint8_t)'X'))) - { - i = 2U; - while ((i < 11U) && (pInputStr[i] != (uint8_t)'\0')) - { - if (ISVALIDHEX(pInputStr[i])) - { - x = CONVERTHEX(pInputStr[i]); - val = (val << 4U) + x; - } - else - { - /* Return 0, Invalid input */ - res = 0U; - break; - } - i++; - } - - /* valid result */ - if (pInputStr[i] == (uint8_t)'\0') - { - *pIntNum = val; - res = 1U; - } - } - else /* max 10-digit decimal input */ - { - while ((i < 11U) && (res != 1U)) - { - if (pInputStr[i] == (uint8_t)'\0') - { - *pIntNum = val; - /* return 1 */ - res = 1U; - } - else if (((pInputStr[i] == (uint8_t)'k') || (pInputStr[i] == (uint8_t)'K')) && (i > 0U)) - { - val = val << 10U; - *pIntNum = val; - res = 1U; - } - else if (((pInputStr[i] == (uint8_t)'m') || (pInputStr[i] == (uint8_t)'M')) && (i > 0U)) - { - val = val << 20U; - *pIntNum = val; - res = 1U; - } - else if (ISVALIDDEC(pInputStr[i])) - { - x = CONVERTDEC(pInputStr[i]); - val = (val * 10U) + x; - } - else - { - /* return 0, Invalid input */ - res = 0U; - break; - } - i++; - } - } - - return res; -} - -/** - * @brief Receive a packet from sender - * @param pData: pointer to received data. - * @param puLength - * 0: end of transmission - * 2: abort by sender - * >0: packet length - * @param uTimeOut: receive timeout (ms). - * @retval HAL_OK: normally return - * HAL_BUSY: abort by user - */ -static HAL_StatusTypeDef ReceivePacket(uint8_t *pData, uint32_t *puLength, uint32_t uTimeout) -{ - uint32_t crc; - uint32_t packet_size = 0U; - HAL_StatusTypeDef status; - SFU_ErrorStatus eRetStatus; - - uint8_t char1; - -#ifdef MINICOM_YMODEM - uint32_t myIdx = 0; /* index indicating where to write in pData */ -#endif /* MINICOM_YMODEM */ - - *puLength = 0U; - - /* This operation could last long. Need to refresh the Watchdog if enabled. It could be implemented as a callback*/ - (void) SFU_LL_SECU_IWDG_Refresh(); - - eRetStatus = SFU_LL_UART_Receive(&char1, 1, uTimeout); - - if (eRetStatus == SFU_SUCCESS) - { - status = HAL_OK; - - switch (char1) - { - case SFU_COM_YMODEM_SOH: - packet_size = SFU_COM_YMODEM_PACKET_SIZE; - break; - case SFU_COM_YMODEM_STX: - packet_size = SFU_COM_YMODEM_PACKET_1K_SIZE; - break; - case SFU_COM_YMODEM_EOT: - break; - case SFU_COM_YMODEM_CA: - if ((SFU_LL_UART_Receive(&char1, 1U, uTimeout) == SFU_SUCCESS) && (char1 == SFU_COM_YMODEM_CA)) - { - packet_size = 2U; - } - else - { - status = HAL_ERROR; - } - break; - case SFU_COM_YMODEM_ABORT1: - case SFU_COM_YMODEM_ABORT2: - status = HAL_BUSY; - break; - case SFU_COM_YMODEM_RB: - (void) SFU_LL_UART_Receive(&char1, 1U, uTimeout); /* Ymodem startup sequence : rb ==> 0x72 + 0x62 + 0x0D */ - (void) SFU_LL_UART_Receive(&char1, 1U, uTimeout); - packet_size = 3U; - break; - default: - status = HAL_ERROR; - break; - } - *pData = char1; - - if (packet_size >= SFU_COM_YMODEM_PACKET_SIZE) - { - -#ifndef MINICOM_YMODEM - eRetStatus = SFU_LL_UART_Receive(&pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX], - (uint16_t) (packet_size + SFU_COM_YMODEM_PACKET_OVERHEAD_SIZE), uTimeout); -#else - eRetStatus = SFU_SUCCESS; - /* Receive byte per byte until no data left or no space left in buffer */ - while ((SFU_SUCCESS == eRetStatus) && - ((myIdx + SFU_COM_YMODEM_PACKET_NUMBER_INDEX) < SFU_COM_YMODEM_PACKET_1K_SIZE + - SFU_COM_YMODEM_PACKET_DATA_INDEX + - SFU_COM_YMODEM_PACKET_TRAILER_SIZE) - ) - { - eRetStatus = SFU_LL_UART_Receive(&pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX + myIdx], - 1U, uTimeout); - myIdx++; - } - - if (myIdx > 1) - { - /* We received some bytes */ - eRetStatus = SFU_SUCCESS; - } -#endif /* MINICOM_YMODEM */ - - /* Simple packet sanity check */ - if (eRetStatus == SFU_SUCCESS) - { - status = HAL_OK; - - if (pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX] != ((pData[SFU_COM_YMODEM_PACKET_CNUMBER_INDEX]) ^ - SFU_COM_YMODEM_NEGATIVE_BYTE)) - { - packet_size = 0U; - status = HAL_ERROR; - } - else - { - /* Check packet CRC*/ - crc = (((uint32_t)pData[ packet_size + SFU_COM_YMODEM_PACKET_DATA_INDEX ]) << 8U) & 0x0000FF00U; - crc += pData[ packet_size + SFU_COM_YMODEM_PACKET_DATA_INDEX + 1U ]; - - /*Configure CRC with 16-bit polynomial*/ - if (SFU_LL_CRC_Config(SFU_CRC_CONFIG_16BIT) == SFU_SUCCESS) - { - if (SFU_LL_CRC_Calculate((uint32_t *)(uint32_t)&pData[SFU_COM_YMODEM_PACKET_DATA_INDEX], packet_size) != crc) - { - packet_size = 0U; - status = HAL_ERROR; - } - - } - else - { - packet_size = 0U; - status = HAL_ERROR; - } - } - } - else - { - status = HAL_ERROR; - } - } - } - else - { - status = HAL_ERROR; - } - - *puLength = packet_size; - return status; -} - -/** - * @brief Ymodem Header Packet Transfer completed callback. - * @param uFileSize: Dimension of the file that will be received. - * @retval None - */ -__weak SFU_ErrorStatus SFU_COM_YMODEM_HeaderPktRxCpltCallback(uint32_t uFileSize) -{ - - /* NOTE : This function should not be modified, when the callback is needed, - the SFU_COM_YMODEM_HeaderPktRxCpltCallback could be implemented in the user file - */ - UNUSED(uFileSize); - return SFU_SUCCESS; -} - -/** - * @brief Ymodem Data Packet Transfer completed callback. - * @param pData: Pointer to the buffer. - * @param uSize: Packet dimension. - * @retval None - */ -__weak SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) -{ - - /* NOTE : This function should not be modified, when the callback is needed, - the SFU_COM_YMODEM_DataPktRxCpltCallback could be implemented in the user file - */ - UNUSED(pData); - UNUSED(uSize); - return SFU_SUCCESS; -} - -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_TEST_PROTECTION) */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_error.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_error.c deleted file mode 100644 index c9e026cb..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_error.c +++ /dev/null @@ -1,606 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_error.c - * @author MCD Application Team - * @brief SFU ERROR - * This file provides set of firmware functions for SB_SFU errors handling. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_fsm_states.h" -#include "sfu_error.h" -#include "sfu_low_level_security.h" -#include "sfu_trace.h" -#include "se_interface_bootloader.h" -#include "sfu_fwimg_services.h" -#include "sfu_boot.h" -#include "sfu_test.h" - - -/* Private function prototypes -----------------------------------------------*/ -static void SFU_EXCPT_RuntimeExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief Set the last execution error. The state of the FSM that generated the error is stored - * @param uLastExecError: the last error to store into the BootInfo structure. - * @note for product with MPU isolation : e_se_status and x_boot_info parameters are defined as static to avoid to - * be located into SE stack. This function can be called from IT and thus use the SE stack (privilege mode). - * SE callgate will generate a reset if the parameters are not well located. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_BOOT_SetLastExecError(uint32_t uLastExecError) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - static SE_StatusTypeDef e_se_status; - static SE_BootInfoTypeDef x_boot_info; - - if (SE_INFO_ReadBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - /* Set the last execution status as a 32-bit data */ - x_boot_info.LastExecError = uLastExecError; - - /* Update the BootInfo shared area according to the modifications above */ - if (SE_INFO_WriteBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - e_ret_status = SFU_SUCCESS; - } - } - - return e_ret_status; -} - - -/** - * @brief Manage the Exception generated by an IRQ - * @param eExceptionId : Exception ID. - * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. - * @note Because of the interruption of the State Machine execution, - * it's not possible to continue without compromising the stability or - * the security of the solution. A System Reset is forced at the end. - * @retval None - */ -void SFU_BOOT_IrqExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId) -{ - SFU_EXCPT_IdTypeDef exception_id; - - /* Check the value */ - exception_id = eExceptionId; - if (!IS_SFU_EXCPT(exception_id)) - { - exception_id = SFU_EXCPT_UNKNOWN; - } - - /* At this point and according to the detected critical exceptions, the execution - itself may be compromised and could not be possible to execute the following instructions. - It's worth trying anyway */ - - /* Try to take an action */ - SFU_EXCPT_RuntimeExceptionHandler(exception_id); - - /* Try to store the detected error */ - (void)SFU_BOOT_SetLastExecError((uint32_t) exception_id); - - /* It's not possible to continue without compromising the stability or the security of the solution. - The State Machine needs to be aborted and a Reset must be triggered */ - SFU_BOOT_ForceReboot(); -} - -/** - * @brief Manage the Error generated during the StateMachine execution - * - * If a specific error has been logged in the BootInfo area it is used. - * Otherwise, a generic exception is derived from the previous FSM state (minimal info). - * Nevertheless, the max.consecutive boot on error counter has priority over all other errors. - * @note This function is called when processing a critical failure - * (called from @ref SFU_BOOT_SM_HandleCriticalFailure in state @ref SFU_STATE_HANDLE_CRITICAL_FAILURE) - * @param eStateMachineState: This parameter can be a value of @ref SFU_BOOT_State_Machine_Structure_definition - * @retval None - */ -void SFU_BOOT_StateExceptionHandler(SFU_BOOT_StateMachineTypeDef eStateMachineState) -{ - SFU_EXCPT_IdTypeDef eExceptionId; - SE_BootInfoTypeDef x_boot_info; /* to retrieve the counter of consecutive errors */ - SE_StatusTypeDef e_se_status; - SFU_EXCPT_IdTypeDef u_specific_LastExecError = SFU_EXCPT_NONE; - - /* Check the parameters */ - assert_param(IS_SFU_SM_STATE(eStateMachineState)); - - /* - * First we retrieve the specific error set when the error was detected if any. - * This gives a chance to set a specific error cause, more detailed than the exceptions computed from the FSM state. - */ - if (SE_INFO_ReadBootInfo(&e_se_status, &x_boot_info) == SE_SUCCESS) - { - u_specific_LastExecError = (SFU_EXCPT_IdTypeDef) x_boot_info.LastExecError; - } /* else keep u_specific_LastExecError as SFU_EXCPT_NONE */ - - switch (eStateMachineState) - { - - case SFU_STATE_CHECK_STATUS_ON_RESET: - eExceptionId = SFU_EXCPT_CHECK_STATUS_ON_RESET_ERR; - break; - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - case SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD: - eExceptionId = SFU_EXCPT_CHECK_NEW_FW_TO_DOWNLOAD_ERR; - break; - - case SFU_STATE_DOWNLOAD_NEW_USER_FW: - eExceptionId = SFU_EXCPT_DOWNLOAD_NEW_USER_FW_ERR; - break; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - - case SFU_STATE_VERIFY_USER_FW_STATUS: - eExceptionId = SFU_EXCPT_VERIFY_USER_FW_STATUS_ERR; - break; - - - case SFU_STATE_VERIFY_USER_FW_SIGNATURE: - eExceptionId = SFU_EXCPT_VERIFY_USER_FW_SIGNATURE_ERR; - break; - - - case SFU_STATE_EXECUTE_USER_FW: - eExceptionId = SFU_EXCPT_EXECUTE_USER_FW_ERR; - break; - - default: - /* Set an unknown error */ - eExceptionId = SFU_EXCPT_UNKNOWN; - break; - } - - if (SFU_EXCPT_NONE != u_specific_LastExecError) - { - /* The specific error cause set at error detection stage has priority over the exception computed from the FSM - state */ - eExceptionId = u_specific_LastExecError; - } /* else go ahead with the exception derived from the FSM state */ - - /* Take an immediate action */ - SFU_EXCPT_RuntimeExceptionHandler(eExceptionId); - - /* Try to store the error inside the BootInfo structure */ - (void)SFU_BOOT_SetLastExecError((uint32_t) eExceptionId); - -} - -/** - * @brief Check exception code among the known list - * @param eExceptionId : Exception ID. - * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ - -SFU_ErrorStatus SFU_EXCPT_Check_Code(SFU_EXCPT_IdTypeDef eExceptionId) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - - switch (eExceptionId) - { - case SFU_EXCPT_WATCHDOG_RESET : - break; - case SFU_EXCPT_MEMORY_FAULT : - break; - case SFU_EXCPT_HARD_FAULT : - break; - case SFU_EXCPT_TAMPERING_FAULT : - break; - case SFU_EXCPT_CHECK_PROTECTIONS_ERR : - break; - case SFU_EXCPT_CHECK_STATUS_ON_RESET_ERR : - break; -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - case SFU_EXCPT_CHECK_NEW_FW_TO_DOWNLOAD_ERR : - break; - case SFU_EXCPT_DOWNLOAD_NEW_USER_FW_ERR : - break; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - case SFU_EXCPT_VERIFY_USER_FW_STATUS_ERR : - break; - case SFU_EXCPT_DECRYPT_NEW_USER_FW_ERR : - break; - case SFU_EXCPT_VERIFY_USER_FW_SIGNATURE_ERR : - break; - case SFU_EXCPT_EXECUTE_USER_FW_ERR : - break; - case SFU_EXCPT_LOCK_SE_SERVICES_ERR : - break; -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - case SFU_EXCPT_FW_TOO_BIG : - break; - case SFU_EXCPT_COM_ERROR : - break; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - case SFU_EXCPT_HEADER_AUTH_FAILED : - break; - case SFU_EXCPT_DECRYPT_FAILURE : - break; - case SFU_EXCPT_SIGNATURE_FAILURE : - break; - case SFU_EXCPT_FLASH_ERROR : - break; - case SFU_EXCPT_FWIMG_MAGIC : - break; - case SFU_EXCPT_INCORRECT_VERSION : - break; - case SFU_EXCPT_UNKNOWN : - break; - default : - break; - } - - return e_ret_status; -} - -/** - * @brief Stop in case of security error - * @param eExceptionId : Exception ID. - * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ - -void SFU_EXCPT_Security_Error(void) -{ - TRACE("\r\n= [SBOOT] Security issue : execution stopped !"); - HAL_Delay(1000); - /* This is the last operation executed. Force a System Reset. */ - NVIC_SystemReset(); -} - -/** - * @brief SFU Exception Initialization. - * @param None. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_EXCPT_Init(void) -{ - SFU_ErrorStatus e_ret_status; - - /* ADD SRC CODE HERE - ... - */ - e_ret_status = SFU_SUCCESS; - - return e_ret_status; -} - -/** - * @brief SFU Exception DeInitialization. - * @param None. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_EXCPT_DeInit(void) -{ - SFU_ErrorStatus e_ret_status; - /* ADD SRC CODE HERE - ... - */ - e_ret_status = SFU_SUCCESS; - - return e_ret_status; -} - -/** - * @brief Manage the Exception/Errors/Fault at reset, - * after reading the stored values related to the last execution errors/status - * @param eExceptionId : Exception ID. - * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. - * @note this function is exported because the reset exceptions are also handled at boot time - * when the last execution status is checked. - * @retval None - */ -void SFU_EXCPT_ResetExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId) -{ - - switch (eExceptionId) - { - - case SFU_EXCPT_WATCHDOG_RESET: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] WATCHDOG RESET FAULT!"); - break; - - default: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - /* As an example all the other errors/exceptions/fault retrieved at reset - and related to the previous execution can be managed at the same way of the - errors/exceptions/fault detected at runtime: See SFU_EXCPT_RuntimeExceptionHandler - */ - break; - } -} - -/** - * @brief Manage the Exception/Errors/Fault at runtime, when detected - * @param eExceptionId : Exception ID. - * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. - * @note A System Reset is forced at the end by the caller of this function. - * WARNING: Be aware that this function can be called by an IRQ while - * using the printf, since the printf is not a reentrant function, and using - * the printf inside this function as well, a fault will likely occur. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static void SFU_EXCPT_RuntimeExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId) -{ - switch (eExceptionId) - { - case SFU_EXCPT_TAMPERING_FAULT: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - /* WARNING: Please consider that at runt-time, this "case" execution is - inside an ISR */ - TRACE_IRQ((uint8_t *)"\r\n= [EXCPT] TAMPERING FAULT!"); - break; - - case SFU_EXCPT_MEMORY_FAULT: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - /* WARNING: Please consider that at run-time, this "case" execution is - inside an ISR */ - TRACE_IRQ((uint8_t *)"\r\n= [EXCPT] MEMORY FAULT!"); - break; - - case SFU_EXCPT_HARD_FAULT: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - /* WARNING: Please consider that at run-time, this "case" execution is - inside an ISR */ - TRACE_IRQ((uint8_t *)"\r\n= [EXCPT] HARD FAULT!"); -#ifdef SFU_TEST_PROTECTION - SFU_TEST_Error(); -#endif /* SFU_TEST_PROTECTION */ - break; - - case SFU_EXCPT_CHECK_STATUS_ON_RESET_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] CHECK ON-RESET FAILED!"); - break; - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - case SFU_EXCPT_CHECK_NEW_FW_TO_DOWNLOAD_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] CHECK FOR NEW FW DOWNLOAD FAILED!"); - break; - - case SFU_EXCPT_DOWNLOAD_NEW_USER_FW_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] FW DOWNLOAD FAILED!"); - break; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - - case SFU_EXCPT_VERIFY_USER_FW_STATUS_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] NOT POSSIBLE TO CHECK THE FW STATUS. FAILURE!"); - break; - - case SFU_EXCPT_DECRYPT_NEW_USER_FW_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] USER FW DECRYPTION FAILED!"); - break; - - - case SFU_EXCPT_VERIFY_USER_FW_SIGNATURE_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] USER FW CANNOT BE VERIFIED. FAILURE!"); - break; - - - case SFU_EXCPT_EXECUTE_USER_FW_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] NOT POSSIBLE TO EXECUTE THE NEW FW. FAILURE!"); - break; - - case SFU_EXCPT_UNKNOWN: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] UNKNOWN FAILURE!"); - break; - - case SFU_EXCPT_LOCK_SE_SERVICES_ERR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] CANNOT CONFIGURE SECURE ENGINE TO RUN THE FIRMWARE!"); - break; - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - case SFU_EXCPT_FW_TOO_BIG: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] BINARY IMAGE TOO BIG TO BE STORED IN DWL SLOT!"); - break; - - case SFU_EXCPT_COM_ERROR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] COM ERROR DURING DOWNLOAD !"); - break; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - - case SFU_EXCPT_HEADER_AUTH_FAILED: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] HEADER AUTHENTICATION FAILURE!"); - break; - - case SFU_EXCPT_DECRYPT_FAILURE: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] DECRYPT FAILURE!"); - break; - - case SFU_EXCPT_SIGNATURE_FAILURE: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] FIRMWARE SIGNATURE CHECK FAILED!"); - break; - - case SFU_EXCPT_FLASH_ERROR: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] FLASH ERROR!"); - break; - - case SFU_EXCPT_FWIMG_MAGIC: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] INTERNAL FWIMG ISSUE!"); - break; - - - case SFU_EXCPT_INCORRECT_VERSION: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] INSTALLATION CANCELLED: FORBIDDEN VERSION!"); - break; - - default: - /* WARNING: This might be generated by an attempted attack, a bug or your code! - Add your code here in order to implement a custom action for this event, - e.g. trigger a mass erase or take any other action in order to - protect your system. - ... - ... - */ - TRACE("\r\n= [EXCPT] UNKNOWN FAILURE!"); - break; - } - -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_error.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_error.h deleted file mode 100644 index b7bb5e14..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_error.h +++ /dev/null @@ -1,143 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_error.h - * @author MCD Application Team - * @brief This file contains the error handling elements for SB_SFU. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_ERROR_H -#define SFU_ERROR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "sfu_def.h" - -/* Exported types ------------------------------------------------------------*/ -/** - * This enum must start from 0. - * When adding a new error in the enum below please also: - * 1. update IS_SFU_EXCPT - * 2. update m_aErrorStrings - */ -typedef enum -{ - SFU_EXCPT_NONE = 0UL, - /* System errors */ - SFU_EXCPT_WATCHDOG_RESET, - SFU_EXCPT_MEMORY_FAULT, - SFU_EXCPT_HARD_FAULT, - SFU_EXCPT_TAMPERING_FAULT, - SFU_EXCPT_CHECK_PROTECTIONS_ERR, - /* Generic errors derived from the FSM state */ - SFU_EXCPT_CHECK_STATUS_ON_RESET_ERR, -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - SFU_EXCPT_CHECK_NEW_FW_TO_DOWNLOAD_ERR, - SFU_EXCPT_DOWNLOAD_NEW_USER_FW_ERR, -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - SFU_EXCPT_VERIFY_USER_FW_STATUS_ERR, - SFU_EXCPT_DECRYPT_NEW_USER_FW_ERR, - SFU_EXCPT_VERIFY_USER_FW_SIGNATURE_ERR, - SFU_EXCPT_EXECUTE_USER_FW_ERR, - /* Specific errors */ - SFU_EXCPT_LOCK_SE_SERVICES_ERR, -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - SFU_EXCPT_FW_TOO_BIG, /* The binary is too big to be installed */ - SFU_EXCPT_COM_ERROR, /* COM error during the local download of the binary */ -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - SFU_EXCPT_HEADER_AUTH_FAILED, /* header authentication failure */ - SFU_EXCPT_DECRYPT_FAILURE, /* Decrypt failure */ - SFU_EXCPT_SIGNATURE_FAILURE, /* Signature check failure */ - SFU_EXCPT_FLASH_ERROR, /* Problem with FLASH */ - SFU_EXCPT_FWIMG_MAGIC, /* Problem with a FWIMG pattern */ - SFU_EXCPT_INCORRECT_VERSION, /* Anti-rollback check rejected the version to be installed */ - /* Unknown error */ - SFU_EXCPT_UNKNOWN -} SFU_EXCPT_IdTypeDef; /*!< Errors, Exception, Faults Id */ - -/* External variables --------------------------------------------------------*/ -#ifdef SFU_DEBUG_MODE -#if defined (SFU_BOOT_C) - -/** - * The following strings associated to the exceptions/errors are used for debugging purpose. - * WARNING: The string array must match perfectly with the @ref SFU_EXCPT_IdTypeDef. - * And the @ref SFU_EXCPT_IdTypeDef enum must be a sequence starting from 0 - */ -char *m_aErrorStrings[] = { "No error. Success.", - "Watchdog error.", - "Memory fault.", - "Hard fault.", - "Tampering fault.", - "Check protections error.", - "Check status on reset error.", -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - "Check new user fw to download error.", - "Download new user fw error.", -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - "Verify user fw status error.", - "Decrypt user fw error.", - "Install user fw error.", - "Verify user fw signature.", - "Resume install new user fw error.", - "Execute user fw error.", - "Max. Consecutive Errors reached.", - "SE lock cannot be set.", -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - "Inconsistent FW size.", - "FW too big.", - "YMODEM com failure.", - "File not correctly received.", - "Header authentication failed.", -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - "Decrypt failure.", - "Signature check failure.", - "Incorrect binary format (not encrypted).", - "Flash error.", - "FWIMG pattern issue.", - "Error while swapping the images in slot #0 and slot #1.", - "Firmware version rejected by anti-rollback check.", - "Unknown error." - }; - -#endif /* SFU_BOOT_C */ -#endif /* SFU_DEBUG_MODE */ - -/* Exported macros -----------------------------------------------------------*/ -#define IS_SFU_EXCPT(EXCPT) (SFU_EXCPT_Check_Code((EXCPT)) == SFU_SUCCESS) /*!< Check validity of exception Id */ - -/* Exported functions ------------------------------------------------------- */ -SFU_ErrorStatus SFU_BOOT_SetLastExecError(uint32_t uLastExecError); -void SFU_BOOT_StateExceptionHandler(SFU_BOOT_StateMachineTypeDef eStateMachineState); -void SFU_BOOT_IrqExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); -SFU_ErrorStatus SFU_EXCPT_Check_Code(SFU_EXCPT_IdTypeDef eExceptionId); -void SFU_EXCPT_Security_Error(void); - -SFU_ErrorStatus SFU_EXCPT_Init(void); -SFU_ErrorStatus SFU_EXCPT_DeInit(void); - -void SFU_EXCPT_ResetExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_ERROR_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_common.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_common.c deleted file mode 100644 index 3462933d..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_common.c +++ /dev/null @@ -1,1003 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_fwimg_common.c - * @author MCD Application Team - * @brief This file provides set of firmware functions to manage the Firmware Images. - * This file contains the "common" functionalities of the image handling. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#define SFU_FWIMG_COMMON_C - -/* Includes ------------------------------------------------------------------*/ -#include -#include "main.h" -#include "sfu_fsm_states.h" /* needed for sfu_error.h */ -#include "sfu_error.h" -#include "sfu_low_level.h" -#include "sfu_low_level_flash_int.h" -#include "sfu_low_level_security.h" -#include "se_interface_bootloader.h" -#include "sfu_interface_crypto_scheme.h" -#include "sfu_fwimg_regions.h" -#include "sfu_fwimg_services.h" -#include "sfu_fwimg_internal.h" -#include "sfu_trace.h" -#include "sfu_boot.h" - - -/* Private variables ---------------------------------------------------------*/ -static uint8_t fw_tag_validated[SFU_NB_MAX_ACTIVE_IMAGE][SE_TAG_LEN]; - -/* Global variables ----------------------------------------------------------*/ -/** - * FWIMG status variables used to log errors and display debug messages. - * This is related to FLASH operations. - * This is handled with STATUS_FWIMG. - */ -SFU_IMG_StatusTypeDef SFU_IMG_Status; -uint32_t SFU_IMG_Line; - -/** - * FW header (metadata) of the active FW in active slot: structured format (access by fields) - */ -SE_FwRawHeaderTypeDef fw_image_header_validated; - -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -/** - * FW header (metadata) of the candidate FW in dwl slot: structured format (access by fields) - */ -SE_FwRawHeaderTypeDef fw_image_header_to_test; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ - -/* Functions Definition : helper ---------------------------------------------*/ -/** - * @brief Memory compare with constant time execution. - * @note Objective is to avoid basic attacks based on time execution - * @param pAdd1 Address of the first buffer to compare - * @param pAdd2 Address of the second buffer to compare - * @param Size Size of the comparison - * @retval SFU_ SUCCESS if equal, a SFU_error otherwise. - */ -SFU_ErrorStatus MemoryCompare(uint8_t *pAdd1, uint8_t *pAdd2, uint32_t Size) -{ - uint8_t result = 0x00U; - uint32_t i; - - for (i = 0U; i < Size; i++) - { - result |= pAdd1[i] ^ pAdd2[i]; - } - - if (result == 0x00U) - { - return SFU_SUCCESS; - } - else - { - return SFU_ERROR; - } -} - - -/** - * @brief Check header signature - * @param pFwImageHeader: pointer to raw header. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus VerifyHeaderSignature(SE_FwRawHeaderTypeDef *pFwImageHeader) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef se_status; - uint8_t result = 0x00U; - uint32_t i; - - /* Check if the FW header is authentic : SFU1 / SFU2 / SFU3 */ - if (SFU_IMG_GetFwImageSlot(pFwImageHeader) != SLOT_INACTIVE) - { - /* Unused bytes should be set at 0x00 value - Comparison with constant time execution */ - for (i = 0U; i < sizeof(pFwImageHeader->Reserved); i++) - { - result |= pFwImageHeader->Reserved[i] ^ 0x00U; - } - - if (result == 0x00U) - { - /* Check signature of the FW header */ - if (SE_VerifyHeaderSignature(&se_status, pFwImageHeader) == SE_SUCCESS) - { - FLOW_STEP(uFlowCryptoValue, FLOW_STEP_AUTHENTICATE); - e_ret_status = SFU_SUCCESS; - } - } - } - - return e_ret_status; -} - - -/** - * @brief Secure Engine Firmware signature verification (FW in non contiguous area). - * It handles Firmware TAG verification of a complete buffer by calling - * SE_AuthenticateFW_Init, SE_AuthenticateFW_Append and SE_AuthenticateFW_Finish inside the firewall. - * @note: AES_GCM tag: In order to verify the TAG of a buffer, the function will re-encrypt it - * and at the end compare the obtained TAG with the one provided as input - * in pSE_GMCInit parameter. - * @note: SHA-256 tag: a hash of the firmware is performed and compared with the digest stored in the Firmware header. - * @param pSE_Status: Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param SlotNumber index of the slot in the list - * @param pSE_Metadata: Firmware metadata. - * @param pSE_Payload: pointer to Payload Buffer descriptor. - * @param SE_FwType: Type of Fw Image. - * This parameter can be SE_FW_IMAGE_COMPLETE or SE_FW_IMAGE_PARTIAL. - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SFU_ErrorStatus VerifyFwSignatureScatter(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, - SE_FwRawHeaderTypeDef *pSE_Metadata, - SE_Ex_PayloadDescTypeDef *pSE_Payload, uint32_t SE_FwType) -{ - SE_ErrorStatus se_ret_status = SE_ERROR; - SFU_ErrorStatus sfu_ret_status = SFU_SUCCESS; - /* Loop variables */ - uint32_t i; - uint32_t j; - /* Variables to handle the FW image chunks to be injected in the verification procedure and the result */ - uint32_t fw_tag_len; /* length of the authentication tag to be verified */ - uint32_t fw_verified_total_size = 0; /* number of bytes that have been processed during authentication check */ - uint32_t fw_chunk_size; /* size of a FW chunk to be verified */ - /* Authentication tag computed in this procedure (to be compared with the one stored in the FW metadata) */ - uint8_t fw_tag_output[SE_TAG_LEN] __attribute__((aligned(4))); - /* FW chunk produced by the verification procedure if any */ - uint8_t fw_chunk[CHUNK_SIZE_SIGN_VERIFICATION] __attribute__((aligned(4))); - /* FW chunk provided as input to the verification procedure */ - uint8_t fw_image_chunk[CHUNK_SIZE_SIGN_VERIFICATION] __attribute__((aligned(4))); - /* Variables to handle the FW image (this will be split in chunks) */ - uint32_t payloadsize; - uint32_t ppayload; - uint32_t scatter_nb; - /* Variables to handle FW image size and tag */ - uint32_t fw_size; - uint8_t *fw_tag; - - /* Check the pointers allocation */ - if ((pSeStatus == NULL) || (pSE_Metadata == NULL) || (pSE_Payload == NULL)) - { - return SFU_ERROR; - } - if ((pSE_Payload->pPayload[0] == 0U) || ((pSE_Payload->pPayload[1] == 0U) && (pSE_Payload->PayloadSize[1] != 0U))) - { - return SFU_ERROR; - } - - /* Check the parameters value and set fw_size and fw_tag to check */ - if (SE_FwType == SE_FW_IMAGE_COMPLETE) - { - fw_size = pSE_Metadata->FwSize; - fw_tag = pSE_Metadata->FwTag; - } - else if (SE_FwType == SE_FW_IMAGE_PARTIAL) - { - fw_size = pSE_Metadata->PartialFwSize; - fw_tag = pSE_Metadata->PartialFwTag; - } - else - { - return SFU_ERROR; - } - - if ((pSE_Payload->PayloadSize[0] + pSE_Payload->PayloadSize[1]) != fw_size) - { - return SFU_ERROR; - } - - /* fix number of scatter block */ - if (pSE_Payload->PayloadSize[1] != 0U) - { - scatter_nb = 2U; - } - else - { - scatter_nb = 1U; - } - - - /* Encryption process*/ - se_ret_status = SE_AuthenticateFW_Init(pSeStatus, pSE_Metadata, SE_FwType); - - /* check for initialization errors */ - if ((se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) - { - for (j = 0; j < scatter_nb; j++) - { - payloadsize = pSE_Payload->PayloadSize[j]; - ppayload = pSE_Payload->pPayload[j]; - i = 0; - fw_chunk_size = CHUNK_SIZE_SIGN_VERIFICATION; - - while ((i < (payloadsize / CHUNK_SIZE_SIGN_VERIFICATION)) && (*pSeStatus == SE_OK) && - (sfu_ret_status == SFU_SUCCESS)) - { - - sfu_ret_status = SFU_LL_FLASH_Read(fw_image_chunk, (uint8_t *)ppayload, fw_chunk_size) ; - if (sfu_ret_status == SFU_SUCCESS) - { - se_ret_status = SE_AuthenticateFW_Append(pSeStatus, fw_image_chunk, (int32_t)fw_chunk_size, - fw_chunk, (int32_t *)&fw_chunk_size); - } - else - { - *pSeStatus = SE_ERR_FLASH_READ; - se_ret_status = SE_ERROR; - sfu_ret_status = SFU_ERROR; - } - ppayload += fw_chunk_size; - fw_verified_total_size += fw_chunk_size; - i++; - } - /* this the last path , size can be smaller */ - fw_chunk_size = pSE_Payload->pPayload[j] + pSE_Payload->PayloadSize[j] - ppayload; - if ((fw_chunk_size != 0U) && (se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) - { - sfu_ret_status = SFU_LL_FLASH_Read(fw_image_chunk, (uint8_t *)ppayload, fw_chunk_size) ; - if (sfu_ret_status == SFU_SUCCESS) - { - - se_ret_status = SE_AuthenticateFW_Append(pSeStatus, fw_image_chunk, - (int32_t)(payloadsize - (i * CHUNK_SIZE_SIGN_VERIFICATION)), - fw_chunk, (int32_t *)&fw_chunk_size); - } - else - { - *pSeStatus = SE_ERR_FLASH_READ; - se_ret_status = SE_ERROR; - sfu_ret_status = SFU_ERROR; - } - fw_verified_total_size += fw_chunk_size; - } - } - } - - if ((sfu_ret_status == SFU_SUCCESS) && (se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) - { - if (fw_verified_total_size <= fw_size) - { - /* Do the Finalization, check the authentication TAG*/ - fw_tag_len = sizeof(fw_tag_output); - se_ret_status = SE_AuthenticateFW_Finish(pSeStatus, fw_tag_output, (int32_t *)&fw_tag_len); - - if ((se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK) && (fw_tag_len == SE_TAG_LEN)) - { - /* Firmware tag verification */ - if (MemoryCompare(fw_tag_output, fw_tag, SE_TAG_LEN) != SFU_SUCCESS) - { - *pSeStatus = SE_SIGNATURE_ERR; - se_ret_status = SE_ERROR; - sfu_ret_status = SFU_ERROR; - - /* Save result for active slot : - to avoid single fault attack the signature will be double checked before UserApp execution */ - if ((SlotNumber >= SLOT_ACTIVE_1) && (SlotNumber < SLOT_DWL_1)) - { - (void) memset(&fw_tag_validated[SlotNumber - SLOT_ACTIVE_1][0U], 0x00, SE_TAG_LEN); - } - } - else - { - FLOW_STEP(uFlowCryptoValue, FLOW_STEP_INTEGRITY); - - /* Save result for active slot : - to avoid single fault attacje the signature will be doble checked before UserApp execution */ - if ((SlotNumber >= SLOT_ACTIVE_1) && (SlotNumber < SLOT_DWL_1)) - { - (void) memcpy(&fw_tag_validated[SlotNumber - SLOT_ACTIVE_1][0U], fw_tag, SE_TAG_LEN); - } - } - } - else - { - sfu_ret_status = SFU_ERROR; - } - } - else - { - sfu_ret_status = SFU_ERROR; - } - } - else - { - sfu_ret_status = SFU_ERROR; - } - return sfu_ret_status; -} - -/** - * @brief Fill authenticated info in SE_FwImage. - * @param SFU_APP_Status - * @param pBuffer - * @param BufferSize - * @retval SFU_SUCCESS if successful, a SFU_ERROR otherwise. - */ -SFU_ErrorStatus ParseFWInfo(SE_FwRawHeaderTypeDef *pFwHeader, uint8_t *pBuffer) -{ - /* Check the pointers allocation */ - if ((pFwHeader == NULL) || (pBuffer == NULL)) - { - return SFU_ERROR; - } - (void) memcpy(pFwHeader, pBuffer, sizeof(*pFwHeader)); - return SFU_SUCCESS; -} - -/** - * @brief Verify Image Header in the slot given as a parameter - * @param SlotNumber index of the slot in the list - * @param pFwImageHeader pointer to a structure to handle the header info (filled by this function) - * @note Not used in Alpha version - - * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. - */ -SFU_ErrorStatus CheckAndGetFWHeader(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFwImageHeader) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* use api read to detect possible ECC error */ - e_ret_status = SFU_LL_FLASH_Read((uint8_t *) pFwImageHeader, (uint8_t *) SlotHeaderAdd[SlotNumber], - sizeof(SE_FwRawHeaderTypeDef)); - if (e_ret_status == SFU_SUCCESS) - { - /* Verify signature */ - e_ret_status = VerifyHeaderSignature(pFwImageHeader); - } - return e_ret_status; -} - -/** - * @brief Verify Fw signature of binary contiguous in flash - * @param pSeStatus pointer giving the SE status result - * @param SlotNumber flash slot to check - * @param pFwImageHeader pointer to fw header - * @param SlotNumber flash slot to check - * @param SE_FwType: Type of Fw Image. - * This parameter can be SE_FW_IMAGE_COMPLETE or SE_FW_IMAGE_PARTIAL. - * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. - */ -SFU_ErrorStatus VerifyFwSignature(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, - SE_FwRawHeaderTypeDef *pFwImageHeader, - uint32_t SE_FwType) -{ - SE_Ex_PayloadDescTypeDef pse_payload; - uint32_t fw_size; - uint32_t fw_offset; - - /* put it OK, to discriminate error in SFU FWIMG parts */ - *pSeStatus = SE_OK; - - /* Check the parameters value */ - if (pFwImageHeader == NULL) - { - return SFU_ERROR; - } - if ((SE_FwType != SE_FW_IMAGE_PARTIAL) && (SE_FwType != SE_FW_IMAGE_COMPLETE)) - { - return SFU_ERROR; - } - - /* Check SE_FwType parameter, and fix size and offset accordingly */ - switch (SE_FwType) - { - case SE_FW_IMAGE_COMPLETE : - fw_size = pFwImageHeader->FwSize; - fw_offset = 0U; - break; - case SE_FW_IMAGE_PARTIAL : - fw_size = pFwImageHeader->PartialFwSize; - fw_offset = pFwImageHeader->PartialFwOffset; - break; - default : - /* error */ - fw_size = 0U; - fw_offset = 0U; - break; - } - - pse_payload.pPayload[0] = SlotStartAdd[SlotNumber] + fw_offset + SFU_IMG_IMAGE_OFFSET; - pse_payload.PayloadSize[0] = fw_size; - pse_payload.pPayload[1] = 0U; - pse_payload.PayloadSize[1] = 0U; - - return VerifyFwSignatureScatter(pSeStatus, SlotNumber, pFwImageHeader, &pse_payload, SE_FwType); -} - -/** - * @brief Verifies the validity of a slot. - * @note Control if there is no additional code beyond the firmware image (malicious SW). - * @param pSlotBegin Start address of a slot. - * @param uSlotSize Size of a slot. - * @param uFwSize Size of the firmware image. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise - */ -SFU_ErrorStatus VerifySlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uFwSize) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - SFU_LL_FLASH_write_t pattern1; - SFU_LL_FLASH_write_t pattern2; - SFU_LL_FLASH_write_t value; - uint32_t pdata; - uint32_t fw_size; - uint32_t slot_begin; - - /* Set dimension to the appropriate length for FLASH programming. - * Example: 64-bit length for L4. - */ - if ((uFwSize % (uint32_t)sizeof(SFU_LL_FLASH_write_t)) != 0U) - { - fw_size = uFwSize + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - (uFwSize % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); - } - else - { - fw_size = uFwSize; - } - - /* Clean-up pattern initialization */ - (void) memset((void *)&pattern1, 0xFF, sizeof(SFU_LL_FLASH_write_t)); - (void) memset((void *)&pattern2, 0x00, sizeof(SFU_LL_FLASH_write_t)); - - /* Clean-up Check operation */ - slot_begin = (uint32_t) pSlotBegin; - for (pdata = slot_begin + SFU_IMG_IMAGE_OFFSET + fw_size; - (pdata < (slot_begin + uSlotSize)) && (e_ret_status == SFU_SUCCESS); - pdata += sizeof(SFU_LL_FLASH_write_t)) - { - e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &value, (uint8_t *) pdata, sizeof(SFU_LL_FLASH_write_t)); - STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); - - if (e_ret_status == SFU_SUCCESS) - { - /* Check is already clean */ - if ((memcmp((void *) &value, (void *) &pattern1, sizeof(SFU_LL_FLASH_write_t)) != 0) && - (memcmp((void *) &value, (void *) &pattern2, sizeof(SFU_LL_FLASH_write_t)) != 0)) - { - e_ret_status = SFU_ERROR; - } - } - - /* Reload watchdoag every 64Kbytes */ - if ((pdata % 0x10000U) == 0U) - { - (void) SFU_LL_SECU_IWDG_Refresh(); - } - } - - return e_ret_status; -} - -/** - * @brief This function clean-up the flash - * @note Not designed to clean-up area inside secure engine isolation. - * @note To clean the slot without erasing the header we write "0x00" except if already written - * @param pSlotBegin Start address of a slot. - * @param uSlotSize Size of a slot. - * @param uOffset Offset in the slot to start cleanup, until end of the slot. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus CleanUpSlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uOffset) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint32_t pdata; - uint32_t slot_begin; - SFU_LL_FLASH_write_t pattern; - SFU_LL_FLASH_write_t value; - SFU_FLASH_StatusTypeDef flash_if_info; - - /* Clean-up pattern initialization */ - (void) memset((void *)&pattern, 0x00, sizeof(SFU_LL_FLASH_write_t)); - - /* Cleaning operation */ - slot_begin = (uint32_t) pSlotBegin; - for (pdata = slot_begin + uOffset; pdata < (slot_begin + uSlotSize); pdata += sizeof(SFU_LL_FLASH_write_t)) - { - e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &value, (uint8_t *) pdata, sizeof(SFU_LL_FLASH_write_t)); - - if (e_ret_status == SFU_SUCCESS) - { - /* If read succeed, then the pattern write is performed only if pattern is not already present */ - if (memcmp((void *) &value, (void *) &pattern, sizeof(SFU_LL_FLASH_write_t)) != 0) - { - e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, (uint8_t *) pdata, (uint8_t *) &pattern, - sizeof(SFU_LL_FLASH_write_t)); - } - } - else - { - /* If read fail, then the write is performed unconditionally */ - e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, (uint8_t *) pdata, (uint8_t *) &pattern, - sizeof(SFU_LL_FLASH_write_t)); - } - - /* Reload Watchdog every 4Kbytes */ - if ((pdata % 0x1000U) == 0U) - { - (void) SFU_LL_SECU_IWDG_Refresh(); - } - } - return e_ret_status; -} - -/* Functions Definition : services ------------------------------------------- */ - -/** - * @brief FW Image Handling (FWIMG) initialization function. - * Checks the validity of the settings related to image handling (slots size and alignments...). - * @note The system initialization must have been performed before calling this function (flash driver ready to be - * used...etc...). - * Must be called first (and once) before calling the other Image handling services. - * @param None. - * @retval SFU_IMG_InitStatusTypeDef SFU_IMG_INIT_OK if successful, an error code otherwise. - */ -SFU_IMG_InitStatusTypeDef SFU_IMG_InitImageHandling(void) -{ - uint32_t i; - SFU_IMG_InitStatusTypeDef e_ret_status = SFU_IMG_INIT_OK; - - /* - * When there is no valid FW in active, the fw_image_header_validated structure is filled with 0s. - * When installing a first FW (after local download) this means that WRITE_TRAILER_MAGIC will write a SWAP magic - * starting with 0s. - * This causes an issue when calling CLEAN_TRAILER_MAGIC (because of this we added an erase that generated - * side-effects). - * To avoid all these problems we can initialize fw_image_header_validated with a non-0 value. - */ - (void) memset((uint8_t *) &fw_image_header_validated, 0xFE, sizeof(fw_image_header_validated)); - - /* - * Sanity check: let's make sure all actives slots are properly aligned with regards to flash constraints - */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { -#if defined(__GNUC__) - __IO uint32_t start_add; - start_add = SlotStartAdd[SLOT_ACTIVE_1 + i]; - if (start_add != 0U) -#else - if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) -#endif /* (__GNUC__) */ - { - if (!IS_ALIGNED(SlotStartAdd[SLOT_ACTIVE_1 + i])) - { - e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; - TRACE("\r\n= [FWIMG] SLOT_ACTIVE_%d (%x) is not properly aligned\r\n", - i + 1U, SlotStartAdd[SLOT_ACTIVE_1 + i]); - } /* else active slot is properly aligned */ - } - } - - - /* - * Sanity check: let's make sure the MAGIC patterns used by the internal algorithms match the FLASH constraints. - */ - if (0U != (uint32_t)(MAGIC_LENGTH % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) - { - e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; - TRACE("\r\n= [FWIMG] magic size (%d) is not matching the FLASH constraints\r\n", MAGIC_LENGTH); - } /* else the MAGIC patterns size is fine with regards to FLASH constraints */ - - /* - * Sanity check: let's make sure the Firmware Header Length is fine with regards to FLASH constraints - */ - if (0U != (uint32_t)(SE_FW_HEADER_TOT_LEN % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) - { - /* The code writing the FW header in FLASH requires the FW Header length to match the FLASH constraints */ - e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; - TRACE("\r\n= [FWIMG] FW Header size (%d) is not matching the FLASH constraints\r\n", SE_FW_HEADER_TOT_LEN); - } /* else the FW Header Length is fine with regards to FLASH constraints */ - - - /* - * Sanity check: let's make sure the active slot headers do not overlap SB code area protected by WRP - */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { -#if defined(__GNUC__) - __IO uint32_t start_add; - start_add = SlotStartAdd[SLOT_ACTIVE_1 + i]; - if (start_add != 0U) -#else - if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) -#endif /* (__GNUC__) */ - { - if (((SlotStartAdd[SLOT_ACTIVE_1 + i] - FLASH_BASE) / FLASH_PAGE_SIZE) <= SFU_PROTECT_WRP_PAGE_END_1) - { - TRACE("\r\n= [FWIMG] SLOT_ACTIVE_%d overlaps SBSFU code area protected by WRP\r\n", i + 1U); - e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; - } - } - } - - - - - - /* - * Sanity check: let's make sure the KMS NVM area does not overlap SB code area - */ - if (!(((SB_REGION_ROM_START) > KMS_DATASTORAGE_END) - || ((SB_REGION_ROM_END) < (KMS_DATASTORAGE_START)))) - { - TRACE("\r\n= [FWIMG] KMS NVM area overlaps SB Code area\r\n"); - e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; - } - - /* - * Sanity check: let's make sure the KMS NVM area does not overlap active slots area - */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) - { - if (!(((SlotStartAdd[SLOT_ACTIVE_1 + i]) > KMS_DATASTORAGE_END) - || ((SlotEndAdd[SLOT_ACTIVE_1 + i]) < (KMS_DATASTORAGE_START)))) - { - TRACE("\r\n= [FWIMG] KMS NVM area overlaps SLOT_ACTIVE_%d area\r\n", i + 1U); - e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; - } - } - } - - - - return e_ret_status; -} - -/** - * @brief This function makes sure the current active firmware will not be considered as valid any more. - * This function alters the FLASH content. - * @note It is up to the caller to make sure the conditions to call this primitive are met (no check performed before - * running the procedure). - * @param SlotNumber index of the slot in the list - * @retval SFU_SUCCESS if successful,SFU_ERROR error otherwise. - */ -SFU_ErrorStatus SFU_IMG_InvalidateCurrentFirmware(uint32_t SlotNumber) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Reload Watchdog */ - (void) SFU_LL_SECU_IWDG_Refresh(); - - /* erase active slot except Header (under SECoreBin protection) for the anti-rollback check during next Fw update */ - e_ret_status = CleanUpSlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), SFU_IMG_IMAGE_OFFSET); - - return (e_ret_status); -} - -/** - * @brief Verifies the validity of the active firmware image metadata. - * @note This function relies on cryptographic procedures and it is up to the caller to make sure the required - * elements have been configured. - * @note This function populates the FWIMG module variable: fw_image_header_validated - * @param SlotNumber index of the slot in the list - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise - */ -SFU_ErrorStatus SFU_IMG_VerifyActiveImgMetadata(uint32_t SlotNumber) -{ - /* - * If the metadata is valid then 'fw_image_header_validated' is filled with the metadata. - */ - return (CheckAndGetFWHeader(SlotNumber, &fw_image_header_validated)); -} - -/** - * @brief Verifies the validity of the active firmware image. - * @note This function relies on cryptographic procedures and it is up to the caller to make sure the required - * elements have been configured. - * Typically, SFU_IMG_VerifyActiveImgMetadata() must have been called first to populate - * fw_image_header_validated. - * @param SlotNumber index of the slot in the list - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise - */ -SFU_ErrorStatus SFU_IMG_VerifyActiveImg(uint32_t SlotNumber) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status = SE_KO; - - /* - * fw_image_header_validated MUST have been populated with valid metadata first, - */ - e_ret_status = VerifyFwSignature(&e_se_status, SlotNumber, &fw_image_header_validated, SE_FW_IMAGE_COMPLETE); -#if defined(SFU_VERBOSE_DEBUG_MODE) - if (SFU_ERROR == e_ret_status) - { - /* We do not memorize any specific error, the FSM state is already providing the info */ - TRACE("\r\n= SFU_IMG_VerifyActiveImg failure with se_status=%d!", e_se_status); - } -#endif /* SFU_VERBOSE_DEBUG_MODE */ - - return (e_ret_status); -} - -/** - * @brief Verifies if no malicious code beyond Fw Image in an active slot. - * @note SFU_IMG_VerifyActiveImgMetadata() must have been called first to populate fw_image_header_validated. - * @param SlotNumber index of the slot in the list - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise - */ -SFU_ErrorStatus SFU_IMG_VerifyActiveSlot(uint32_t SlotNumber) -{ - /* - * fw_image_header_validated MUST have been populated with valid metadata first, - */ - return (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), fw_image_header_validated.FwSize)); -} - -/** - * @brief Verifies if no malicious code in active slot. - * @param SlotNumber index of the slot in the list - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise - */ -SFU_ErrorStatus SFU_IMG_VerifyEmptyActiveSlot(uint32_t SlotNumber) -{ - return (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), 0U)); -} - -/** - * @brief Control firmware signature - * @note This control will be done twice for security reasons (first control done in VerifyFwSignatureScatter) - * @param SlotNumber index of the slot in the list - * @retval SFU_SUCCESS if successful,SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_IMG_ControlActiveImgTag(uint32_t SlotNumber) -{ - /* - * fw_image_header_validated MUST have been populated with valid metadata first, - */ - if (MemoryCompare(fw_tag_validated[SlotNumber - SLOT_ACTIVE_1], fw_image_header_validated.FwTag, - SE_TAG_LEN) != SFU_SUCCESS) - { - return SFU_ERROR; - } - else - { - FLOW_STEP(uFlowCryptoValue, FLOW_STEP_INTEGRITY); - return SFU_SUCCESS; - } - -} - -/** - * @brief Launches the user application. - * The caller must be prepared to never get the hand back after calling this function. - * If a problem occurs, it must be memorized in the bootinfo area. - * If the caller gets the hand back then this situation must be handled as a critical error. - * @note It is up to the caller to make sure the conditions to call this primitive are met - * (typically: no security check performed before launching the firmware). - * @note This function only handles the "system" aspects. - * It is up to the caller to manage any security related action (enable ITs, disengage MPU, clean RAM...). - * Nevertheless, cleaning-up the stack and heap used by SB_SFU is part of the system actions handled by this - * function (as this needs to be done just before jumping into the user application). - * @param SlotNumber index of the slot in the list - * @retval SFU_ErrorStatus Does not return if successful, returns SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_IMG_LaunchActiveImg(uint32_t SlotNumber) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - - /* Verify if authentication/integrity/lock SE service performed */ - FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_LOCK_SERVICE); - - uint32_t jump_address ; - typedef void (*Function_Pointer)(void); - Function_Pointer p_jump_to_function; - -#if defined(SFU_MPU_PROTECT_ENABLE) -#if defined(SFU_MPU_USERAPP_ACTIVATION) - e_ret_status = SFU_LL_SECU_SetProtectionMPU_UserApp(); -#else - HAL_MPU_Disable(); -#endif /* SFU_MPU_USERAPP_ACTIVATION */ -#endif /* SFU_MPU_PROTECT_ENABLE */ - - jump_address = *(__IO uint32_t *)((SlotStartAdd[SlotNumber] + SFU_IMG_IMAGE_OFFSET + 4)); - /* Jump to user application */ - p_jump_to_function = (Function_Pointer) jump_address; - /* Initialize user application's Stack Pointer */ - __set_MSP(*(__IO uint32_t *)(SlotStartAdd[SlotNumber] + SFU_IMG_IMAGE_OFFSET)); - - /* Configure active slot area in execution mode if required (external flash) */ - if (SFU_SUCCESS == e_ret_status) - { - e_ret_status = SFU_LL_FLASH_Config_Exe(SlotNumber); - } - - if (SFU_SUCCESS == e_ret_status) - { - /* JUMP into User App */ - p_jump_to_function(); - } - - /* The point below should NOT be reached */ - return (e_ret_status); -} - -/** - * @brief Get the version of the active FW - * @note It is up to the caller to make sure the active slot contains a valid active FW. - * @note In the current implementation the header is checked (authentication) and no version is returned if this check - * fails. - * @param SlotNumber index of the slot in the list - * @retval the FW version if the header is valid (coded on uint16_t), 0 otherwise - */ -uint16_t SFU_IMG_GetActiveFwVersion(uint32_t SlotNumber) -{ - SE_FwRawHeaderTypeDef fw_image_header; - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint16_t version = 0; - - /* check the header of the active FW */ - e_ret_status = CheckAndGetFWHeader(SlotNumber, &fw_image_header); - if (e_ret_status == SFU_SUCCESS) - { - /* retrieve the version from the header without any further check */ - version = fw_image_header.FwVersion; - } - - return (version); -} - -/** - * @brief Detect if a FW is present in a slot. - * @note Detection done based on MAGIC header + FW signature. Header verification - * not done at this stage for timing optimization. - * @param SlotNumber index of the slot in the list - * @retval SFU_SUCCESS if successful, error code otherwise - */ -SFU_ErrorStatus SFU_IMG_DetectFW(uint32_t SlotNumber) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint8_t *pbuffer; - uint8_t buffer[SE_FW_HEADER_TOT_LEN]; - SE_FwRawHeaderTypeDef *p_header; - - /* Read header */ - pbuffer = (uint8_t *) SlotHeaderAdd[SlotNumber]; - if (SFU_LL_FLASH_Read(buffer, pbuffer, sizeof(buffer)) == SFU_SUCCESS) - { - /* Check if the FW header is authentic : SFU1 / SFU2 / SFU3 */ - p_header = (SE_FwRawHeaderTypeDef *)(uint32_t)buffer; - if (SFU_IMG_GetFwImageSlot(p_header) != SLOT_INACTIVE) - { - /* - * Control if the first 32 bytes (could be more but time consuming ...) are significants - * At this location we should find the vector table. - * Objective is to detect if the FW image has been erased - * ==> this is the case after SFU_IMG_InvalidateCurrentFirmware() (could be an attack attempt) - */ - if (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SFU_IMG_IMAGE_OFFSET + 0x20U, 0U) != SFU_SUCCESS) - { - e_ret_status = SFU_SUCCESS; - } - } - } - return e_ret_status; -} - -/** - * @brief Validate the active FW image in active slot by installing the header - * @param SlotNumber index of the slot in the list - * @param pFwImageHeader pointer in ram to the header to install - * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. - */ - -SFU_ErrorStatus SFU_IMG_Validation(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFWImageHeader) -{ -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SFU_FLASH_StatusTypeDef flash_if_status; - - /* Header writing: encrypted part with signature */ - e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *) SlotHeaderAdd[SlotNumber], (uint8_t *) pFWImageHeader, - SE_FW_AUTH_LEN + SE_FW_HEADER_SIGN_LEN); - STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); - - /* Header writing : Do not update image state part */ - - /* Header writing: previous FW image fingerprint */ - if (e_ret_status == SFU_SUCCESS) - { - e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *)(SlotHeaderAdd[SlotNumber] + SE_FW_HEADER_TOT_LEN - - SE_FW_HEADER_FINGERPRINT_LEN), - (uint8_t *) pFWImageHeader->PrevHeaderFingerprint, SE_FW_HEADER_FINGERPRINT_LEN); - STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); - } - return e_ret_status; -#else - /* Nothing to do header already written */ - return SFU_SUCCESS; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ -} - -/** - * @brief Get firmware image ID from header. - * @param pFwImageHeader pointer to a structure to handle the header info - * @retval Fw Id : SLOT_ACTIVE_1 / 2 /... / SFU_NB_MAX_ACTIVE_IMAGE - */ -uint32_t SFU_IMG_GetFwImageSlot(SE_FwRawHeaderTypeDef *pFwImageHeader) -{ - uint32_t active_slot; - - if (memcmp(pFwImageHeader->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) - { - active_slot = SLOT_ACTIVE_1; - } -#if (SFU_NB_MAX_ACTIVE_IMAGE > 1) - else if (memcmp(pFwImageHeader->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) - { - active_slot = SLOT_ACTIVE_2; - } -#endif /* (SFU_NB_MAX_ACTIVE_IMAGE > 1) */ -#if (SFU_NB_MAX_ACTIVE_IMAGE > 2) - else if (memcmp(pFwImageHeader->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) - { - active_slot = SLOT_ACTIVE_3; - } -#endif /* (SFU_NB_MAX_ACTIVE_IMAGE > 2) */ - else - { - active_slot = SLOT_INACTIVE; - } - - return active_slot; -} - -/** - * @brief Check candidate image version is allowed. - * @param CurrentVersion Version of currently installed image if any - * @param CandidateVersion Version of candidate image - * @retval SFU_SUCCESS if candidate image version is allowed, SFU_ErrorStatus error otherwise. - */ -SFU_ErrorStatus SFU_IMG_CheckFwVersion(uint16_t CurrentVersion, uint16_t CandidateVersion) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - - /* If the headre of the active firmware is not valid, the CurrentVersion is 0 */ - if (CurrentVersion == 0U) - { - /* - * If the header of the active firmware is not valide (could comes from an attak atempt, we authorize only the - * installation of a specific version identified by SFU_FW_VERSION_INIT_NUM. - */ - if (CandidateVersion == SFU_FW_VERSION_INIT_NUM) - { - /* Candidate version is allowed */ - e_ret_status = SFU_SUCCESS; - } - } - else - { - /* - * It is not allowed to install a Firmware with a lower version than the active firmware. - * But we authorize the re-installation of the current firmware version. - * We also check that the candidate version is at least the min. allowed version for this device. - */ - if ((CandidateVersion >= CurrentVersion) && (CandidateVersion >= SFU_FW_VERSION_START_NUM)) - { - /* Candidate version is allowed */ - e_ret_status = SFU_SUCCESS; - } - } - - return e_ret_status; -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_internal.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_internal.h deleted file mode 100644 index a09e993b..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_internal.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_fwimg_internal.h - * @author MCD Application Team - * @brief This file contains internal definitions (private) for SFU_FWIMG functionalities. - * This file should be included only by sfu_fwimg_core.c and sfu_fwimg_services.c. - * Nevertheless, the SFU_KMS module is allowed to include it to re-use the variable - * fw_image_header_to_test to install an KMS blob. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_FWIMG_INTERNAL_H -#define SFU_FWIMG_INTERNAL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "se_def.h" -#include "sfu_fwimg_regions.h" -#include "kms_blob_metadata.h" - -/* Exported types ------------------------------------------------------------*/ -/** - * @brief Payload Buffer descriptor. - * This structure describes how a Firmware is split in Flash. - * In the nominal case a Firmware is stored in 1 contiguous area. - * But, a Firmware can be split in up to 2 areas (typically when a FW installation procedure is interrupted or after a - * decrypt operation). - */ -typedef struct -{ - uint32_t pPayload[2]; /*!< table containing payload pointer*/ - uint32_t PayloadSize[2]; /*!< table containing Payload Size*/ -} SE_Ex_PayloadDescTypeDef; - -/* Exported constants --------------------------------------------------------*/ -/** - * @brief SFU_IMG Flash Status Type Definition - * Status of a FLASH operation. - */ -typedef enum -{ - SFU_IMG_OK = 0x0U, /*!< No problem reported */ - SFU_IMG_FLASH_ERASE_FAILED, /*!< FLASH erase failure */ - SFU_IMG_FLASH_WRITE_FAILED, /*!< FLASH write failure */ - SFU_IMG_FLASH_READ_FAILED, /*!< FLASH read failure */ -} SFU_IMG_StatusTypeDef; - -/** - * @brief RAM chunk used for decryption / comparison / swap - * it is the size of RAM buffer allocated in stack and used for decrypting/moving images. - * some function allocates 2 buffer of this size in stack. - * As image are encrypted by 128 bits blocks, this value is 16 bytes aligned. - */ -#define VALID_SIZE (3U*MAGIC_LENGTH) -#define CHUNK_SIZE_SIGN_VERIFICATION (1024UL) /*!< Signature verification chunk size*/ - -#define SFU_IMG_CHUNK_SIZE (512UL) -#define AES_BLOCK_SIZE (16UL) /*!< Size of an AES block to check padding needs for decrypting */ - -/* Exported macros -----------------------------------------------------------*/ -/** - * @brief Status Macro - * This macros aims at capturing abnormal errors in the FWIMG sub-module (typically FLASH errors). - * When SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is activated this macro blocks the execution. - * When SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is deactivated, a log is printed in the console (if SFU_DEBUG_MODE is - * activated) and the execution continues. - */ -#if defined(SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE) -#define STATUS_FWIMG(B,A) if (B) { \ - SFU_IMG_Status=A; \ - SFU_IMG_Line = __LINE__; \ - TRACE("\r\n Abnormal error %d at line %d in %s - BLOCK", \ - SFU_IMG_Status, SFU_IMG_Line, __FILE__); \ - while(1==1){;} \ - } while(0==1){;} -#else -#define STATUS_FWIMG(B,A) if (B) { \ - SFU_IMG_Status=A; \ - SFU_IMG_Line = __LINE__; \ - TRACE("\r\n Abnormal error %d at line %d in %s - CONTINUE", \ - SFU_IMG_Status, SFU_IMG_Line, __FILE__); \ - } while(0==1){;} -#endif /* SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE */ - -/* External variables --------------------------------------------------------*/ -/** - * FWIMG status variables used to log errors and display debug messages. - * This is related to FLASH operations. - * This is handled with STATUS_FWIMG. - */ -extern SFU_IMG_StatusTypeDef SFU_IMG_Status; -extern uint32_t SFU_IMG_Line; - -extern SE_FwRawHeaderTypeDef fw_image_header_validated; -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -extern SE_FwRawHeaderTypeDef fw_image_header_to_test; -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ - -/* Exported functions : helper ---------------------------------------------- */ -SFU_ErrorStatus MemoryCompare(uint8_t *pAdd1, uint8_t *pAdd2, uint32_t Size); -SFU_ErrorStatus VerifyHeaderSignature(SE_FwRawHeaderTypeDef *pFwImageHeader); -SFU_ErrorStatus VerifyFwSignatureScatter(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, - SE_FwRawHeaderTypeDef *pSE_Metadata, - SE_Ex_PayloadDescTypeDef *pSE_Payload, uint32_t SE_FwType); -SFU_ErrorStatus VerifyTag(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pSE_Metadata, - uint8_t *pPayload, uint32_t SE_FwType); -SFU_ErrorStatus ParseFWInfo(SE_FwRawHeaderTypeDef *pFwHeader, uint8_t *pBuffer); -SFU_ErrorStatus CheckAndGetFWHeader(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFwImageHeader); -SFU_ErrorStatus VerifyFwSignature(SE_StatusTypeDef *pSeStatus, uint32_t slot, SE_FwRawHeaderTypeDef *pFwImageHeader, - uint32_t SE_FwType); -SFU_ErrorStatus VerifySlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uFwSize); -SFU_ErrorStatus CleanUpSlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uOffset); - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_FWIMG_INTERNAL_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_regions.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_regions.h deleted file mode 100644 index c4d0c847..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_regions.h +++ /dev/null @@ -1,104 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_fwimg_regions.h - * @author MCD Application Team - * @brief This file contains FLASH regions definitions for SFU_FWIMG functionalities - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_FWIMG_REGIONS_H -#define SFU_FWIMG_REGIONS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "app_sfu.h" -#if defined(__ARMCC_VERSION) -#include "mapping_fwimg.h" -#elif defined (__ICCARM__) || defined(__GNUC__) -#include "mapping_export.h" -#endif /* __ARMCC_VERSION */ -#include "se_crypto_config.h" - - -/* Exported constants --------------------------------------------------------*/ -/** - * Slot list : 2 slots per image configuration + swap - */ -#define NB_SLOTS 4U -#define SLOT_INACTIVE 0U /* this index should not be used ==> no tag found in the header */ -#define SLOT_ACTIVE_1 1U -#define SLOT_DWL_1 2U -#define SLOT_SWAP 3U - - -/* Calculation of the size of a slot */ -#define SLOT_SIZE(a) (SlotEndAdd[a] - SlotStartAdd[a] + 1U) - -/* - * Design constraint: the image slot size must be a multiple of the swap area size. - * And of course both image slots must have the same size. - */ -#define SFU_IMG_REGION_IS_MULTIPLE(a,b) ((a / b * b) == a) - -/* - * Checking that the slot sizes are consistent with the .icf file - * Sizes expressed in bytes (+1 because the end address belongs to the slot) - * The checks are executed at runtime in the SFU_Img_Init() function. - */ -#define SFU_IMG_REGION_IS_SAME_SIZE(a,b) ((a) == (b)) - -/** - * Image starting offset to add to the address of 1st block - */ -#define SFU_IMG_IMAGE_OFFSET ((uint32_t)512U) - - -/* External variables --------------------------------------------------------*/ -extern const uint32_t SlotHeaderAdd[NB_SLOTS]; -extern const uint32_t SlotStartAdd[NB_SLOTS]; -extern const uint32_t SlotEndAdd[NB_SLOTS]; - -#if defined(SFU_FWIMG_COMMON_C) || defined(SE_LOW_LEVEL_C) || defined(TEST_PROTECTIONS_C) || defined(SFU_LOADER_C) - -const uint32_t SlotHeaderAdd[NB_SLOTS] = { 0U, - SLOT_ACTIVE_1_HEADER, - SLOT_BLOB_DWL_1_START, - 0U, - }; -/* List of slot start address */ -const uint32_t SlotStartAdd[NB_SLOTS] = { 0U, - SLOT_ACTIVE_1_START, - SLOT_BLOB_DWL_1_START, - 0U, - }; -/* List of slot end address */ -const uint32_t SlotEndAdd[NB_SLOTS] = { 0U, - SLOT_ACTIVE_1_END, - SLOT_BLOB_DWL_1_END, - 0U, - }; -#endif /* SFU_FWIMG_COMMON_C || SE_LOW_LEVEL_C || TEST_PROTECTIONS_C || SFU_LOADER_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_FWIMG_REGIONS_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_services.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_services.h deleted file mode 100644 index 3cff72a2..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fwimg_services.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_fwimg_services.h - * @author MCD Application Team - * @brief This file contains the 2 images handling service (SFU_FWIMG functionalities) - * API definitions. - * These services can be called by the bootloader to deal with images handling. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_FWIMG_SERVICES_H -#define SFU_FWIMG_SERVICES_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "se_def.h" -#include "sfu_def.h" - -/* Exported types ------------------------------------------------------------*/ -/** - * @brief SFU_IMG Initialization Status Type Definition - */ -typedef enum -{ - SFU_IMG_INIT_OK = 0x0U, /*!< SFU Firmware Image Handling (FWIMG) Init OK */ - SFU_IMG_INIT_SLOTS_SIZE_ERROR, /*!< error related to slots size */ - SFU_IMG_INIT_SWAP_SETTINGS_ERROR, /*!< error related to swap settings */ - SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR, /*!< error related to flash constraints */ - SFU_IMG_INIT_CRYPTO_CONSTRAINTS_ERROR, /*!< error related to crypto constraints */ - SFU_IMG_INIT_ERROR /*!< Init is FAILED: unspecified error */ -} SFU_IMG_InitStatusTypeDef; - -/** - * @brief SFU_IMG Image Installation State Type Definition - */ -typedef enum -{ - SFU_IMG_FWIMAGE_TO_INSTALL = 0x0U, /*!< There is a FW image to be installed */ - SFU_IMG_FWUPDATE_STOPPED, /*!< A previous installation has been interrupted before it completed : resume installation */ - SFU_IMG_NO_FWUPDATE, /*!< No FW image installation pending */ - SFU_IMG_FWIMAGE_ROLLBACK, /*!< A new FW image installation has not been validated : rollback initiated @ next reset */ -} SFU_IMG_ImgInstallStateTypeDef; - -/* Exported functions ------------------------------------------------------- */ -SFU_IMG_InitStatusTypeDef SFU_IMG_InitImageHandling(void); -SFU_IMG_InitStatusTypeDef SFU_IMG_CheckSwapImageHandling(void); -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -SFU_IMG_ImgInstallStateTypeDef SFU_IMG_CheckPendingInstallation(uint32_t *pDwlSlotToInstall); -#else -SFU_IMG_ImgInstallStateTypeDef SFU_IMG_CheckPendingInstallation(uint32_t *pDwlSlotToInstall, \ - uint32_t *pActiveSlotToResume, \ - uint32_t *pActiveSlotToRollback); -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ -SFU_ErrorStatus SFU_IMG_TriggerImageInstallation(uint32_t DwlSlot); -SFU_ErrorStatus SFU_IMG_TriggerResumeInstallation(uint32_t ActiveSlot, uint32_t DwlSlot); -#ifdef ENABLE_IMAGE_STATE_HANDLING -SFU_ErrorStatus SFU_IMG_TriggerRollbackInstallation(uint32_t ActiveSlot, uint32_t DwlSlot); -SFU_ErrorStatus SFU_IMG_UpdateImageState(uint32_t SlotNumber); -#endif /* ENABLE_IMAGE_STATE_HANDLING */ -SFU_ErrorStatus SFU_IMG_EraseDownloadedImg(uint32_t DwlSlot); -uint32_t SFU_IMG_GetTrailerSize(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_InvalidateCurrentFirmware(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_VerifyActiveImgMetadata(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_VerifyActiveImg(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_VerifyActiveSlot(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_VerifyEmptyActiveSlot(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_LaunchActiveImg(uint32_t SlotNumber); -uint16_t SFU_IMG_GetActiveFwVersion(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_DetectFW(uint32_t SlotNumber); -SFU_ErrorStatus SFU_IMG_Validation(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFWImageHeader); -SFU_ErrorStatus SFU_IMG_ControlActiveImgTag(uint32_t SlotNumber); -uint32_t SFU_IMG_GetFwImageSlot(SE_FwRawHeaderTypeDef *pFwImageHeader); -SFU_ErrorStatus SFU_IMG_CheckFwVersion(uint16_t CurrentVersion, uint16_t CandidateVersion); - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_FWIMG_SERVICES_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c deleted file mode 100644 index 0b3acd0b..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c +++ /dev/null @@ -1,701 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_interface_crypto_scheme.c - * @author MCD Application Team - * @brief Secure Engine Interface module. - * This file provides set of firmware functions to manage SE Interface - * functionalities. These services are used by the bootloader. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" /* se_interface_bootloader.c is compiled in SBSFU project using main.h from this project */ -#include "se_low_level.h" /* This file is part of SE_CoreBin and adapts the Secure Engine (and its interface) to the - STM32 board specificities */ -#include "tkms.h" -#include "sfu_interface_crypto_scheme.h" -#include -#include "kms_platf_objects_interface.h" - -/* Private defines -----------------------------------------------------------*/ -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) -#define GCM_TAGBITS_SIZE 128 -#define GCM_IVLEN_BITS 16 -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - -/* Private variables ---------------------------------------------------------*/ -CK_SESSION_HANDLE EncryptSession; -CK_SESSION_HANDLE DecryptSession; -CK_SESSION_HANDLE AuthenticateSession; -CK_SESSION_HANDLE VerifySession; -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) -static uint8_t *gcm_tag_header; -#endif /* SECBOOT_CRYPTO_SCHEME */ - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief Get AES key handle. - * @param pxSE_Metadata Metadata that will be used to identify the keys. - * @param phAESKey pointer on AES key object handle - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) -static SE_ErrorStatus SFU_GetAESKeyObject(SE_FwRawHeaderTypeDef *pxSE_Metadata, CK_OBJECT_HANDLE *phAESKey) -{ - SE_ErrorStatus e_ret_status = SE_ERROR; - - /* Identify the slot number */ - if (memcmp(pxSE_Metadata->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) - { - *phAESKey = KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE; - e_ret_status = SE_SUCCESS; - } -#if (SFU_NB_MAX_ACTIVE_IMAGE > 1U) - else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) - { - *phAESKey = KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE; - e_ret_status = SE_SUCCESS; - } -#endif /* (NB_FW_IMAGES > 1) */ -#if (SFU_NB_MAX_ACTIVE_IMAGE > 2U) - else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) - { - *phAESKey = KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE; - e_ret_status = SE_SUCCESS; - } -#endif /* (NB_FW_IMAGES > 2) */ - else - { - e_ret_status = SE_ERROR; - } - - return e_ret_status; -} -#endif /* ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) */ - -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) -/** - * @brief Get ECDSA key handle. - * @param pxSE_Metadata Metadata that will be used to identify the keys. - * @param phAESKey pointer on AES key object handle - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -static SE_ErrorStatus SFU_GetECDSAKeyObject(SE_FwRawHeaderTypeDef *pxSE_Metadata, CK_OBJECT_HANDLE *phECDSAKey) -{ - SE_ErrorStatus e_ret_status = SE_ERROR; - - /* Identify the slot number */ - if (memcmp(pxSE_Metadata->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) - { - *phECDSAKey = KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE; - e_ret_status = SE_SUCCESS; - } -#if (SFU_NB_MAX_ACTIVE_IMAGE > 1U) - else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) - { - *phECDSAKey = KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE; - e_ret_status = SE_SUCCESS; - } -#endif /* (NB_FW_IMAGES > 1) */ -#if (SFU_NB_MAX_ACTIVE_IMAGE > 2U) - else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) - { - *phECDSAKey = KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE; - e_ret_status = SE_SUCCESS; - } -#endif /* (NB_FW_IMAGES > 2) */ - else - { - e_ret_status = SE_ERROR; - } - - return e_ret_status; -} -#endif /*((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) */ - - -/** - * @brief Secure Engine Decrypt Init function. - * It is a wrapper of Decrypt_Init function included in the protected area. - * @param peSE_Status Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param pxSE_Metadata Metadata that will be used to fill the Crypto Init structure. - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SFU_Decrypt_Init(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxSE_Metadata, uint32_t SE_FwType) -{ - SE_ErrorStatus se_status = SE_SUCCESS; - *peSE_Status = SE_OK; - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - CK_RV rv = CKR_OK; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - uint8_t *gcm_iv = pxSE_Metadata->Nonce; - CK_OBJECT_HANDLE hAESKey = 0UL; - - CK_GCM_PARAMS kms_test_gcm_params = - { - (CK_BYTE *)gcm_iv, - SE_NONCE_LEN, - NULL, - 0, - GCM_TAGBITS_SIZE - }; - - CK_MECHANISM cktest_aes_gcm_mechanism = - { - CKM_AES_GCM, - (CK_VOID_PTR *) &kms_test_gcm_params, - sizeof(kms_test_gcm_params) - }; - - gcm_tag_header = pxSE_Metadata->FwTag; - -#elif (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) - CK_RV rv = CKR_OK; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - uint8_t *iv_cbc = pxSE_Metadata->InitVector; - CK_OBJECT_HANDLE hAESKey = 0UL; - - CK_MECHANISM cktest_aes_cbc_mechanism = - { - CKM_AES_CBC, - iv_cbc, - SE_IV_LEN - }; -#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 - /* - * In this crypto scheme the Firmware is not encrypted. - * The Decrypt operation is called anyhow before installing the firmware. - * Indeed, it allows moving the Firmware image blocks in FLASH. - * These moves are mandatory to create the appropriate mapping in FLASH - * allowing the swap procedure to run without using the swap area at each and every move. - * - * See in SB_SFU project: @ref SFU_IMG_PrepareCandidateImageForInstall. - */ -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - - /* Check the pointer allocation */ - if (pxSE_Metadata == NULL) - { - return SE_ERROR; - } -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) - /* Initialize the KMS service */ - C_Initialize(NULL) ; - - /* Start by opening a session */ - rv = C_OpenSession(0, session_flags, NULL, 0, &DecryptSession); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* Identify the keys after FW header analysis (magic tag) */ - if (SFU_GetAESKeyObject(pxSE_Metadata, &hAESKey) != SE_SUCCESS) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } -#endif /* (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) */ - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - /* Initialize the decryption session */ - rv = C_DecryptInit(DecryptSession, &cktest_aes_gcm_mechanism, hAESKey); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#elif (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) - /* Initialize the decryption session */ - rv = C_DecryptInit(DecryptSession, &cktest_aes_cbc_mechanism, hAESKey); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 - /* Nothing to do as we won't decrypt anything */ -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - - return se_status; -} - -/** - * @brief Secure Engine Decrypt Append function. - * It is a wrapper of Decrypt_Append function included in the protected area. - * @param peSE_Status Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param pInputBuffer pointer to Input Buffer. - * @param uInputSize Input Size (bytes). - * @param pOutputBuffe pointer to Output Buffer. - * @param puOutputSize pointer to Output Size (bytes). - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SFU_Decrypt_Append(SE_StatusTypeDef *peSE_Status, const uint8_t *pInputBuffer, int32_t InputSize, - uint8_t *pOutputBuffer, int32_t *pOutputSize) -{ - SE_ErrorStatus se_status = SE_SUCCESS; - *peSE_Status = SE_OK; -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ - || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) - CK_RV rv = CKR_OK; -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ - - /* DecryptImageInDwlSlot() always starts by calling the Decrypt service with a 0 byte buffer */ - if (0 == InputSize) - { - /* Nothing to do but we must return a success for the decrypt operation to continue */ - return (SE_SUCCESS); - } - - /* Check the pointers allocation */ - if ((pInputBuffer == NULL) || (pOutputBuffer == NULL) || (pOutputSize == NULL)) - { - return SE_ERROR; - } - -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ - || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) - /* Buffer decryption */ - rv = C_DecryptUpdate(DecryptSession, (CK_BYTE *)pInputBuffer, InputSize, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } -#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 - /* - * The firmware is not encrypted. - * The only thing we need to do is to recopy the input buffer in the output buffer - */ - (void)memcpy(pOutputBuffer, pInputBuffer, (uint32_t)InputSize); - *pOutputSize = InputSize; - se_status = SE_SUCCESS; -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ - - return se_status; -} - -/** - * @brief Secure Engine Decrypt Finish function. - * It is a wrapper of Decrypt_Finish function included in the protected area. - * @param peSE_Status Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param pOutputBuffer pointer to Output Buffer. - * @param puOutputSize pointer to Output Size (bytes). - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SFU_Decrypt_Finish(SE_StatusTypeDef *peSE_Status, uint8_t *pOutputBuffer, int32_t *pOutputSize) -{ - *peSE_Status = SE_OK; - SE_ErrorStatus se_status = SE_SUCCESS; -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) - CK_RV rv = CKR_OK; -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ - - /* Check the pointers allocation */ - if ((pOutputBuffer == NULL) || (pOutputSize == NULL)) - { - return SE_ERROR; - } - -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ - || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) - memcpy(pOutputBuffer, gcm_tag_header, 16); - - /* End-up decryption session */ - rv = C_DecryptFinal(DecryptSession, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 - /* Nothing to do */ - se_status = SE_SUCCESS; -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) - /* Close the session */ - rv = C_CloseSession(DecryptSession); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* End-up the KMS service */ - C_Finalize(NULL) ; -#endif /* (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) */ - - return se_status; -} - -/** - * @brief Secure Engine Firmware Authentication Init function. - * It is a wrapper of AuthenticateFW_Init function included in the Firewall. - * @param peSE_Status Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param pxSE_Metadata Metadata that will be used to fill the Crypto Init structure. - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SFU_AuthenticateFW_Init(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxSE_Metadata, - uint32_t SE_FwType) -{ - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - CK_RV rv = CKR_OK; - SE_ErrorStatus se_status = SE_SUCCESS; - *peSE_Status = SE_OK; - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - uint8_t *gcm_iv = pxSE_Metadata->Nonce; - CK_OBJECT_HANDLE hAESKey; - - CK_GCM_PARAMS kms_test_gcm_params = - { - (CK_BYTE *)gcm_iv, - SE_NONCE_LEN, - NULL, - 0, - GCM_TAGBITS_SIZE - }; - - CK_MECHANISM cktest_aes_gcm_mechanism = - { - CKM_AES_GCM, - (CK_VOID_PTR *) &kms_test_gcm_params, - sizeof(kms_test_gcm_params) - }; - -#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) - CK_MECHANISM cktest_sha_256_mechanism = - { - CKM_SHA256, - NULL, - 0 - }; -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - - /* Check the pointer allocation */ - if (pxSE_Metadata == NULL) - { - return SE_ERROR; - } - - /* Initialize the KMS service */ - C_Initialize(NULL) ; - - /* Start by opening a session */ - rv = C_OpenSession(0, session_flags, NULL, 0, &AuthenticateSession); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - /* Identify the keys after FW header analysis (magic tag) */ - if (SFU_GetAESKeyObject(pxSE_Metadata, &hAESKey) != SE_SUCCESS) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* Initialize encryption session */ - rv = C_EncryptInit(AuthenticateSession, &cktest_aes_gcm_mechanism, hAESKey); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) - /* Digest initialization */ - rv = C_DigestInit(AuthenticateSession, &cktest_sha_256_mechanism); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - - return se_status; -} - -/** - * @brief Secure Engine Firmware Authentication Append function. - * It is a wrapper of AuthenticateFW_Append function included in the Firewall. - * @param peSE_Status Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param pInputBuffer pointer to Input Buffer. - * @param uInputSize Input Size (bytes). - * @param pOutputBuffer pointer to Output Buffer. - * @param puOutputSize pointer to Output Size (bytes). - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SFU_AuthenticateFW_Append(SE_StatusTypeDef *peSE_Status, const uint8_t *pInputBuffer, int32_t InputSize, - uint8_t *pOutputBuffer, int32_t *pOutputSize) -{ - SE_ErrorStatus se_status = SE_SUCCESS; - CK_RV rv = CKR_OK; - - /* Check the pointers allocation */ - if ((pInputBuffer == NULL) || (pOutputBuffer == NULL) || (pOutputSize == NULL)) - { - return SE_ERROR; - } - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - /* Buffer encryption */ - rv = C_EncryptUpdate(AuthenticateSession, (CK_BYTE *)pInputBuffer, InputSize, pOutputBuffer, - (CK_ULONG_PTR)pOutputSize); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } -#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) - /* Digest calculation */ - rv = C_DigestUpdate(AuthenticateSession, (CK_BYTE_PTR)pInputBuffer, InputSize); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - - return se_status; -} - -/** - * @brief Secure Engine Firmware Authentication Finish function. - * It is a wrapper of AuthenticateFW_Finish function included in the Firewall. - * @param peSE_Status Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param pOutputBuffer pointer to Output Buffer. - * @param puOutputSize pointer to Output Size (bytes). - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SFU_AuthenticateFW_Finish(SE_StatusTypeDef *peSE_Status, uint8_t *pOutputBuffer, int32_t *pOutputSize) -{ - SE_ErrorStatus se_status = SE_SUCCESS; - CK_RV rv = CKR_OK; - - /* Check the pointers allocation */ - if ((pOutputBuffer == NULL) || (pOutputSize == NULL)) - { - return SE_ERROR; - } - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - /* End-up encryption session */ - rv = C_EncryptFinal(AuthenticateSession, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } -#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) - /* End-up Digest calculation */ - rv = C_DigestFinal(AuthenticateSession, (CK_BYTE_PTR)pOutputBuffer, (CK_ULONG_PTR)pOutputSize); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - - /* Close the session */ - rv = C_CloseSession(AuthenticateSession); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* End-up the KMS service */ - C_Finalize(NULL) ; - - return se_status; -} - -/** - * @brief Secure Engine Verify Raw Fw Header Tag. - * It verifies the signature of a raw header file. - * @param peSE_Status Secure Engine Status. - * This parameter can be a value of @ref SE_Status_Structure_definition. - * @param pFwRawHeader pointer to RawHeader Buffer. - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SFU_VerifyHeaderSignature(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxFwRawHeader) -{ - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - CK_RV rv = CKR_OK; - SE_ErrorStatus se_status = SE_SUCCESS; - *peSE_Status = SE_OK; - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - int32_t fw_raw_header_output_length = SE_TAG_LEN; - uint8_t *gcm_iv = pxFwRawHeader->Nonce; - SE_FwRawHeaderTypeDef *gcm_header = pxFwRawHeader; - CK_OBJECT_HANDLE hAESKey = 0UL; - - CK_GCM_PARAMS kms_test_gcm_params = - { - (CK_BYTE *)gcm_iv, - SE_NONCE_LEN, - (CK_BYTE_PTR)gcm_header, - ((int32_t)SE_FW_AUTH_LEN), - GCM_TAGBITS_SIZE - }; - - CK_MECHANISM cktest_aes_gcm_mechanism = - { - CKM_AES_GCM, - (CK_VOID_PTR *) &kms_test_gcm_params, - sizeof(kms_test_gcm_params) - }; - -#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)\ - || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) - - const uint8_t *pPayload; /* Metadata payload */ - int32_t payloadSize; /* Metadata length to be considered for hash */ - uint8_t *pSignature = pxFwRawHeader->HeaderSignature; /* Signature ECDSA */ - CK_OBJECT_HANDLE hECDSAKey = 0UL; - CK_MECHANISM cktest_ecdsa_256_mechanism = - { - CKM_ECDSA_SHA256, - NULL, - 0 - }; -#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ - - /* Check the pointers allocation */ - if (NULL == pxFwRawHeader) - { - *peSE_Status = SE_KO; - return SE_ERROR; - } - -#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) - gcm_tag_header = pxFwRawHeader->HeaderSignature; -#endif /* SECBOOT_CRYPTO_SCHEME */ - - - /* Initialize the KMS service */ - C_Initialize(NULL) ; - - /* Start by opening a session */ - rv = C_OpenSession(0, session_flags, NULL, 0, &VerifySession); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) - /* Identify the keys after FW header analysis (magic tag) */ - if (SFU_GetAESKeyObject(pxFwRawHeader, &hAESKey) != SE_SUCCESS) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* Initialize the decryption session */ - rv = C_DecryptInit(VerifySession, &cktest_aes_gcm_mechanism, hAESKey); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* End-up decryption session : control if the tag is correct */ - rv = C_DecryptFinal(VerifySession, gcm_tag_header, (CK_ULONG_PTR)&fw_raw_header_output_length); - - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)\ - || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) - - pPayload = (const uint8_t *)pxFwRawHeader; - payloadSize = SE_FW_AUTH_LEN; /* Authenticated part of the header */ - - /* Identify the keys after FW header analysis (magic tag) */ - if (SFU_GetECDSAKeyObject(pxFwRawHeader, &hECDSAKey) != SE_SUCCESS) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* Initialize the verification process */ - rv = C_VerifyInit(VerifySession, &cktest_ecdsa_256_mechanism, hECDSAKey); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* End-up verification process : control if the signature is correct */ - rv = C_Verify(VerifySession, (CK_BYTE_PTR)pPayload, payloadSize, (CK_BYTE_PTR)pSignature, SE_HEADER_SIGN_LEN); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - -#else -#error "The current example does not support the selected crypto scheme." -#endif /* SECBOOT_CRYPTO_SCHEME */ - - /* Close the session */ - rv = C_CloseSession(VerifySession); - if (rv != CKR_OK) - { - se_status = SE_ERROR; - *peSE_Status = SE_KO; - } - - /* End-up the KMS service */ - C_Finalize(NULL) ; - - return se_status; - -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_loader.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_loader.c deleted file mode 100644 index 8df9adb7..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_loader.c +++ /dev/null @@ -1,811 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_loader.c - * @author MCD Application Team - * @brief Secure Firmware Update LOADER module. - * This file provides set of firmware functions to manage SFU local - * loader functionalities. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include -#include -#include "main.h" -#include "sfu_loader.h" -#include "sfu_low_level_flash_int.h" -#include "sfu_low_level_security.h" -#include "sfu_com_loader.h" -#include "sfu_trace.h" -#include "se_interface_bootloader.h" /* for metadata authentication */ -#include "sfu_interface_crypto_scheme.h" -#include "sfu_fwimg_services.h" /* for version checking & to check if a valid FW is installed (the local - bootloader is a kind of "application" running in SB_SFU) */ -#include "app_sfu.h" - -#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) - -/* Private variables ---------------------------------------------------------*/ -static uint8_t -fw_decrypted_chunk[SFU_COM_YMODEM_PACKET_1K_SIZE];/*!< Buffer used for decryption during reception process */ -static uint32_t m_uDwlAreaAddress = 0U; /*!< Address of to write in download area */ -static uint32_t m_uDwlAreaStart = 0U; /*!< Address of download area */ -static uint32_t m_uDwlAreaSize = 0U; /*!< Size of download area */ -static uint32_t m_uFileSizeYmodem = 0U; /*!< Ymodem file size being received */ -static uint32_t m_uNbrBlocksYmodem = 0U; /*!< Number of blocks being received via Ymodem*/ -static uint32_t m_uPacketsReceived = 0U; /*!< Number of packets received via Ymodem*/ -static uint32_t m_uDwlSlot = SLOT_INACTIVE; /*!< Dwl slot identification : to be intialialized after header check */ -static SFU_LOADER_StatusTypeDef m_LoaderStatus; /*!< Status of the loader */ - -/* Private function prototypes -----------------------------------------------*/ -static SFU_ErrorStatus SFU_LOADER_VerifyFwHeader(uint8_t *pBuffer); - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief Initialize the SFU LOADER. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LOADER_Init(void) -{ - /* - * ADD SRC CODE HERE - */ - - /* - * Sanity check to make sure that the local loader cannot read out of the buffer bounds - * when doing a length alignment before writing in FLASH. - */ - if (0U != (uint32_t)(sizeof(fw_decrypted_chunk) % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) - { - /* The decrypt buffer must be a multiple of the FLASH write length */ - TRACE("\r\n= [FWIMG] Decrypt buffer size (%d) is not matching the FLASH constraints", sizeof(fw_decrypted_chunk)); - return SFU_ERROR; - } /* else the FW Header Length is fine with regards to FLASH constraints */ - - return SFU_SUCCESS; -} - -/** - * @brief DeInitialize the SFU LOADER. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LOADER_DeInit(void) -{ - /* - * ADD SRC CODE HERE - */ - return SFU_SUCCESS; -} - -/** - * @brief Download a new User Fw. - * Writes firmware received via Ymodem in FLASH. - * @param peSFU_LOADER_Status: SFU LOADER Status. - * This parameter can be a value of @ref SFU_LOADER_Status_Structure_definition. - * @param p_DwlSlot identification of the downloaded area - * @param p_Size Size of the downloaded image. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LOADER_DownloadNewUserFw(SFU_LOADER_StatusTypeDef *peSFU_LOADER_Status, uint32_t *pDwlSlot, - uint32_t *pSize) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SFU_COM_YMODEM_StatusTypeDef e_com_status = SFU_COM_YMODEM_ERROR; - SE_StatusTypeDef e_se_status; - int32_t fw_tag_len = 0; - uint8_t fw_tag_output[SE_TAG_LEN]; - - /* Check the pointers allocation */ - if ((peSFU_LOADER_Status == NULL) || (pSize == NULL) || (pDwlSlot == NULL)) - { - return SFU_ERROR; - } - - /* Refresh Watchdog */ - (void) SFU_LL_SECU_IWDG_Refresh(); - - /* Transfer FW Image via YMODEM protocol */ - TRACE("\r\n\t File> Transfer> YMODEM> Send "); - - /* Initialize global variables to be used during the YMODEM process */ - m_uDwlAreaAddress = 0U; - m_uDwlAreaStart = 0U; - m_uDwlAreaSize = 0U; - m_uFileSizeYmodem = 0U; - m_uNbrBlocksYmodem = 0U; - m_uPacketsReceived = 0U; - m_uDwlSlot = SLOT_ACTIVE_1; - m_LoaderStatus = SFU_LOADER_ERR_COM; - - /* Receive the FW in RAM and write it in the Flash*/ - if (SFU_COM_YMODEM_Receive(&e_com_status, pSize) == SFU_SUCCESS) - { - if (*pSize > 0U) - { - /* File download correct*/ - m_LoaderStatus = SFU_LOADER_OK; - } - } - else - { - /* Nothing to do : m_LoaderStatus updated during during YModem process */ - } - - /* Provide slot information to the caller - m_uDwlSlot updated during VerifyFwHeader() except in case of bad formatted file - ==> m_uDwlSlot stick at SLOT_DWL_1 value if the header signature is not verified */ - *pDwlSlot = m_uDwlSlot; - - if (m_LoaderStatus == SFU_LOADER_OK) - { - /* End of decryption process */ - fw_tag_len = sizeof(fw_tag_output); - if (SE_Decrypt_Finish(&e_se_status, fw_tag_output, &fw_tag_len) != SE_SUCCESS) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - - } - else if (e_se_status != SE_OK) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - } - else - { - /* Nothing */ - } - } - - *peSFU_LOADER_Status = m_LoaderStatus; - if (m_LoaderStatus == SFU_LOADER_OK) - { - e_ret_status = SFU_SUCCESS; - } - return e_ret_status; -} - -/** - * @brief Ymodem Header Packet Transfer completed callback. - * @param uFileSize: Dimension of the file that will be received. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_COM_YMODEM_HeaderPktRxCpltCallback(uint32_t uFileSize) -{ - /*Reset of the ymodem variables */ - m_uFileSizeYmodem = 0U; - m_uPacketsReceived = 0U; - m_uNbrBlocksYmodem = 0U; - - /*Filesize information is stored*/ - m_uFileSizeYmodem = uFileSize; - - /*Compute the number of blocks */ -#ifndef MINICOM_YMODEM - /* Teraterm sends 1kB YMODEM packets */ - m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (SFU_COM_YMODEM_PACKET_1K_SIZE - 1U)) / SFU_COM_YMODEM_PACKET_1K_SIZE; -#else - /* Minicom sends 128 bytes YMODEM packets */ - m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (SFU_COM_YMODEM_PACKET_SIZE - 1U)) / SFU_COM_YMODEM_PACKET_SIZE; -#endif /* MINICOM_YMODEM */ - - /* NOTE : delay inserted for Ymodem protocol*/ - HAL_Delay(1000U); - - return SFU_SUCCESS; -} - -/** - * @brief Ymodem Data Packet Transfer completed callback. - * @param pData: Pointer to the buffer. - * @param uSize: Packet dimension. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -#ifndef MINICOM_YMODEM -/* Teraterm variant of the YMODEM protocol: uses 1kB packets */ -SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) -{ - /* The local loader must make a copy of the Firmware metadata, - * because this memory area is not copied when calling the SE_Decrypt_Init() primitive. - * Hence we must make sure this memory area still contains the FW header when SE_Decrypt_Finish() is called. */ - static uint8_t fw_header[SE_FW_HEADER_TOT_LEN] __attribute__((aligned(4))); - /* Size of downloaded Image initialized with first packet (header) and checked along download process */ - static uint32_t m_uDwlImgSize = 0U; - - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - SFU_FLASH_StatusTypeDef x_flash_info; - uint32_t rx_size = uSize; - uint8_t *p_data = pData; - uint32_t uOldSize; - int32_t fw_decrypted_chunk_size; - SE_StatusTypeDef e_se_status = SE_KO; - - /* Check the pointers allocation */ - if (p_data == NULL) - { - return SFU_ERROR; - } - - /*Increase the number of received packets*/ - m_uPacketsReceived++; - - /* Last packet : size of data to write could be different than SFU_COM_YMODEM_PACKET_1K_SIZE */ - if (m_uPacketsReceived == m_uNbrBlocksYmodem) - { - /*Extracting actual payload from last packet*/ - if (0U == (m_uFileSizeYmodem % SFU_COM_YMODEM_PACKET_1K_SIZE)) - { - /* The last packet must be fully considered */ - rx_size = SFU_COM_YMODEM_PACKET_1K_SIZE; - } - else - { - /* The last packet is not full, drop the extra bytes */ - rx_size = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / SFU_COM_YMODEM_PACKET_1K_SIZE) * - SFU_COM_YMODEM_PACKET_1K_SIZE); - } - } - - /* First packet : Contains the FW header (SE_FW_HEADER_TOT_LEN bytes length) which is not encrypted */ - if (m_uPacketsReceived == 1U) - { - - (void) memcpy(fw_header, p_data, SE_FW_HEADER_TOT_LEN); - - /* Verify header */ - e_ret_status = SFU_LOADER_VerifyFwHeader(p_data); - if (e_ret_status == SFU_SUCCESS) - { - m_uDwlAreaAddress = m_uDwlAreaStart; - - /* Downloaded Image size : Header size + Image size */ - m_uDwlImgSize = ((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header)->FwSize + SFU_IMG_IMAGE_OFFSET; - } - - /* Clear Download application area (including TRAILERS area) */ - if (e_ret_status == SFU_SUCCESS) - { - if (SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) m_uDwlAreaAddress, SLOT_SIZE(m_uDwlSlot)) != - SFU_SUCCESS) - { - m_LoaderStatus = SFU_LOADER_ERR_FLASH; - e_ret_status = SFU_ERROR; - } - } - - /* Initialize decryption process */ - if (e_ret_status == SFU_SUCCESS) - { - if (SE_Decrypt_Init(&e_se_status, (SE_FwRawHeaderTypeDef *)fw_header, SE_FW_IMAGE_COMPLETE) != SE_SUCCESS) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else if (e_se_status != SE_OK) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else - { - /* Store FW image header in Flash */ - if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, p_data, SE_FW_HEADER_TOT_LEN) == SFU_SUCCESS) - { - /* Shift the DWL area pointer */ - m_uDwlAreaAddress += SE_FW_HEADER_TOT_LEN; - rx_size -= SE_FW_HEADER_TOT_LEN; - p_data += SE_FW_HEADER_TOT_LEN; - } - else - { - m_LoaderStatus = SFU_LOADER_ERR_FLASH; - e_ret_status = SFU_ERROR; - } - } - } - } - - if (e_ret_status == SFU_SUCCESS) - { - /* if the data is part of SFU_IMG_IMAGE_OFFSET nothing to do ==> padding */ - if (m_uDwlAreaAddress < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) - { - /* all the data are located inside SFU_IMG_IMAGE_OFFSET : nothing to do ==> full padding */ - if ((m_uDwlAreaAddress + rx_size) < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) - { - m_uDwlAreaAddress += rx_size; - p_data += rx_size; - rx_size = 0U; - } - /* part of the data is inside SFU_IMG_IMAGE_OFFSET ==> remaining bytes to be deccrypted */ - else - { - rx_size -= (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); - p_data += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); - m_uDwlAreaAddress += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); - } - } - - /* remaining bytes to decrypt ? */ - if (rx_size != 0U) - { - fw_decrypted_chunk_size = rx_size; - if ((e_ret_status == SFU_SUCCESS) - && (SE_Decrypt_Append(&e_se_status, p_data, rx_size, fw_decrypted_chunk, &fw_decrypted_chunk_size) - != SE_SUCCESS)) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else if ((e_se_status != SE_OK) || (fw_decrypted_chunk_size != rx_size)) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else - { - /*Nothing */ - } - } - } - - - if (e_ret_status == SFU_SUCCESS) - { - /* Check size to avoid writing beyond DWL image size */ - if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlImgSize)) - { - m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; - e_ret_status = SFU_ERROR; - } - } - - if (e_ret_status == SFU_SUCCESS) - { - /* Set dimension to the appropriate length for FLASH programming. - * Example: 64-bit length for L4. - */ - if ((rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t)) != 0U) - { - /* By construction, the length of the buffer (fw_decrypted_chunk or p_data) must be a multiple of - sizeof(SFU_IMG_write_t) to avoid reading out of the buffer */ - uOldSize = rx_size; - rx_size = rx_size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - (rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); - while (uOldSize < rx_size) - { - p_data[uOldSize] = 0xFF; - uOldSize++; - } - } - } - - if (e_ret_status == SFU_SUCCESS) - { - /* Check size to avoid writing beyond DWL area */ - if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlAreaSize)) - { - m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; - e_ret_status = SFU_ERROR; - } - } - - /* Write Data in Flash */ - if (e_ret_status == SFU_SUCCESS) - { - if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, fw_decrypted_chunk, rx_size) == SFU_SUCCESS) - { - m_uDwlAreaAddress += (rx_size); - } - else - { - m_LoaderStatus = SFU_LOADER_ERR_FLASH; - e_ret_status = SFU_ERROR; - } - } - - - /* Last packet : reset m_uPacketsReceived */ - if (m_uPacketsReceived == m_uNbrBlocksYmodem) - { - m_uPacketsReceived = 0U; - } - - /* Reset data counters in case of error */ - if (e_ret_status == SFU_ERROR) - { - /*Reset of the ymodem variables */ - m_uFileSizeYmodem = 0U; - m_uPacketsReceived = 0U; - m_uNbrBlocksYmodem = 0U; - } - - return e_ret_status; -} -#else /* MINICOM_YMODEM */ -/* Minicom variant of the YMODEM protocol: uses 128B packets */ -SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) -{ - /* The local loader must make a copy of the Firmware metadata, - * because this memory area is not copied when calling the SE_Decrypt_Init() primitive. - * Hence we must make sure this memory area still contains the FW header when SE_Decrypt_Finish() is called. */ - static uint8_t fw_header[SE_FW_HEADER_TOT_LEN] __attribute__((aligned(4))); - /* Size of downloaded Image initialized with first packet (header) and checked along download process */ - static uint32_t m_uDwlImgSize = 0U; - - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - SFU_FLASH_StatusTypeDef x_flash_info; - uint32_t rx_size = uSize; - uint8_t *p_data = pData; - uint32_t uOldSize; - int32_t fw_decrypted_chunk_size; - SE_StatusTypeDef e_se_status = SE_KO; - - /* Check the pointers allocation */ - if (p_data == NULL) - { - return SFU_ERROR; - } - - /*Increase the number of received packets*/ - m_uPacketsReceived++; - - /* Last packet : size of data to write could be different than SFU_COM_YMODEM_PACKET_1K_SIZE */ - if (m_uPacketsReceived == m_uNbrBlocksYmodem) - { - /*Extracting actual payload from last packet: minicom works by default with 128B packets */ - if (0 == (m_uFileSizeYmodem % SFU_COM_YMODEM_PACKET_SIZE)) - { - /* The last packet must be fully considered */ - rx_size = SFU_COM_YMODEM_PACKET_SIZE; - } - else - { - /* The last packet is not full, drop the extra bytes: minicom works by default with 128B packets */ - rx_size = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / SFU_COM_YMODEM_PACKET_SIZE) * - SFU_COM_YMODEM_PACKET_SIZE); - } - } - - - /* - * Minicom splits the header of 192 bytes on 2 packets of 128 bytes. - */ - - /* First packet : Contains the first 128B of FW header (out of SE_FW_HEADER_TOT_LEN bytes length) which is - not encrypted */ - if (1 == m_uPacketsReceived) - { - /* First packet: beginning of header */ - if (SFU_COM_YMODEM_PACKET_SIZE == rx_size) - { - /* Copy the beginning of the header */ - memcpy(fw_header, p_data, rx_size); - rx_size = 0U; /* nothing more to do */ - } - else - { - /* Unexpected case */ - e_ret_status = SFU_ERROR; - } - } - else if (2U == m_uPacketsReceived) - { - /* Second packet: end of header (64 bytes) */ - memcpy(fw_header + SFU_COM_YMODEM_PACKET_SIZE, p_data, 64U); - rx_size -= 64U; - p_data += 64U; - - /* Verify header */ - e_ret_status = SFU_LOADER_VerifyFwHeader(fw_header); - - if (e_ret_status == SFU_SUCCESS) - { - m_uDwlAreaAddress = m_uDwlAreaStart; - /* Downloaded Image size : Header size + Image size */ - m_uDwlImgSize = ((SE_FwRawHeaderTypeDef *)fw_header)->FwSize + SFU_IMG_IMAGE_OFFSET; - - /* Clear Download application area (including TRAILERS area) */ - if ((e_ret_status == SFU_SUCCESS) - && (SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) m_uDwlAreaAddress, SLOT_SIZE(m_uDwlSlot)) != - SFU_SUCCESS)) - { - m_LoaderStatus = SFU_LOADER_ERR_FLASH; - e_ret_status = SFU_ERROR; - } - - if (e_ret_status == SFU_SUCCESS) - { - /* Initialize decryption process */ - if ((e_ret_status == SFU_SUCCESS) - && (SE_Decrypt_Init(&e_se_status, (SE_FwRawHeaderTypeDef *)fw_header, SE_FW_IMAGE_COMPLETE) != SE_SUCCESS)) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else if (e_se_status != SE_OK) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else - { - /* Write the FW header (SE_FW_HEADER_TOT_LEN bytes length) at start of DWL area */ - if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, fw_header, SE_FW_HEADER_TOT_LEN) - == SFU_SUCCESS) - { - /* Shift the DWL area pointer */ - m_uDwlAreaAddress += SE_FW_HEADER_TOT_LEN; - } - else - { - m_LoaderStatus = SFU_LOADER_ERR_FLASH; - e_ret_status = SFU_ERROR; - } - } - } - /* The remaining 64 bytes of data must be handled : standard processing */ - } - } - /* - * Else: standard packet data processing based on rx_size (full packet or the last 64 bytes of the 2nd packet) - */ - if (e_ret_status == SFU_SUCCESS) - { - /* - * if the data is part of SFU_IMG_IMAGE_OFFSET nothing to do ==> padding - */ - if (m_uDwlAreaAddress < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) - { - if ((m_uDwlAreaAddress + rx_size) < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) - { - /* all the data are located inside SFU_IMG_IMAGE_OFFSET : nothing to do ==> full padding */ - m_uDwlAreaAddress += rx_size; - p_data += rx_size; - rx_size = 0U; - } - else - { - /* part of the data is inside SFU_IMG_IMAGE_OFFSET ==> remaining bytes to be decrypted */ - rx_size -= (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); - p_data += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); - m_uDwlAreaAddress += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); - } - } - - /* remaining bytes to decrypt ? */ - if (rx_size != 0) - { - fw_decrypted_chunk_size = rx_size; - if ((e_ret_status == SFU_SUCCESS) - && (SE_Decrypt_Append(&e_se_status, p_data, rx_size, fw_decrypted_chunk, &fw_decrypted_chunk_size) - != SE_SUCCESS)) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else if ((e_se_status != SE_OK) || (fw_decrypted_chunk_size != rx_size)) - { - m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; - e_ret_status = SFU_ERROR; - } - else - { - /*Nothing */ - } - - /* Check size to avoid writing beyond DWL image size */ - if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlImgSize)) - { - m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; - e_ret_status = SFU_ERROR; - } - - /* Set dimension to the appropriate length for FLASH programming. - * Example: 64-bit length for L4. - */ - if ((rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t)) != 0) - { - /* By construction, the length of the buffer (fw_decrypted_chunk or p_data) must be a multiple of - sizeof(SFU_IMG_write_t) to avoid reading out of the buffer */ - uOldSize = rx_size; - rx_size = rx_size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - (rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); - while (uOldSize < rx_size) - { - p_data[uOldSize] = 0xFF; - uOldSize++; - } - } - - /* Check size to avoid writing beyond DWL area */ - if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlAreaSize)) - { - m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; - e_ret_status = SFU_ERROR; - } - - /* Write Data in Flash */ - if (e_ret_status == SFU_SUCCESS) - { - if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, fw_decrypted_chunk, rx_size) == SFU_SUCCESS) - { - m_uDwlAreaAddress += (rx_size); - } - else - { - m_LoaderStatus = SFU_LOADER_ERR_FLASH; - e_ret_status = SFU_ERROR; - } - } - } - } - - - /* Last packet : reset m_uPacketsReceived */ - if (m_uPacketsReceived == m_uNbrBlocksYmodem) - { - m_uPacketsReceived = 0U; - } - - /* Reset data counters in case of error */ - if (e_ret_status == SFU_ERROR) - { - /*Reset of the ymodem variables */ - m_uFileSizeYmodem = 0U; - m_uPacketsReceived = 0U; - m_uNbrBlocksYmodem = 0U; - } - - return e_ret_status; -} -#endif /* MINICOM_YMODEM */ - - -/** - * @brief Verifies the Raw Fw Header received. It checks if the header is - * authentic and if the fields are ok with the device (e.g. size and version). - * @note Please note that when the new image is installed, this metadata is checked - * by @ref SFU_IMG_CheckCandidateVersion. - * @param peSFU_LOADER_Status: SFU LOADER Status. - * This parameter can be a value of @ref SFU_LOADER_Status_Structure_definition. - * @param pBuffer: pointer to header Buffer. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ - -/* anti-rollback mechanism is tested twice to avoid basic hardware attack - ==> compiler optimization is disabled for this reason */ -#if defined(__ICCARM__) -#pragma optimize=none -#elif defined(__CC_ARM) -#pragma O0 -#elif defined(__ARMCC_VERSION) -__attribute__((optnone)) -#elif defined(__GNUC__) -__attribute__((optimize("O0"))) -#endif /* __ICCARM__ */ - -static SFU_ErrorStatus SFU_LOADER_VerifyFwHeader(uint8_t *pBuffer) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_StatusTypeDef e_se_status; - SE_FwRawHeaderTypeDef *p_x_fw_raw_header; - SFU_FwImageFlashTypeDef fw_image_flash_data; - uint16_t curVer; - uint32_t active_slot; - - /*Parse the received buffer*/ - p_x_fw_raw_header = (SE_FwRawHeaderTypeDef *)(uint32_t)pBuffer; - /*Check if the received header packet is authentic*/ - if (SE_VerifyHeaderSignature(&e_se_status, p_x_fw_raw_header) != SE_ERROR) - { - active_slot = SFU_IMG_GetFwImageSlot(p_x_fw_raw_header); - /* - * 1 slot per image configuration. Identify the download area. - * It will be based on SFU magic : - * - dwl slot is the active_slot if configured. - * - else : SLOT_ACTIVE_1 - */ - m_uDwlSlot = active_slot; - if (SLOT_SIZE(m_uDwlSlot) == 0U) - { - m_uDwlSlot = SLOT_ACTIVE_1; - } - SFU_IMG_GetDownloadAreaInfo(m_uDwlSlot, &fw_image_flash_data); - - /* Assign the download flash address to be used during the YMODEM process */ - m_uDwlAreaStart = fw_image_flash_data.DownloadAddr; - m_uDwlAreaSize = fw_image_flash_data.MaxSizeInBytes; - - /* - * Check if the version is allowed - * ==> SFU_IMG_GetActiveFwVersion() returns 0 if the header of active firmware is not valid - */ - curVer = SFU_IMG_GetActiveFwVersion(active_slot); - if (SFU_IMG_CheckFwVersion(curVer, p_x_fw_raw_header->FwVersion) == SFU_SUCCESS) - { - /* Anti-rollback check pass */ -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n Anti-rollback: candidate version(%d) accepted | current version(%d) , min.version(%d) !", - p_x_fw_raw_header->FwVersion, curVer, SFU_FW_VERSION_START_NUM); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - - /* - * Check length : Let's make sure the Firmware image can be written in the destination slot. - */ - if (p_x_fw_raw_header->FwSize > (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) - { - /* The firmware cannot be written in dwl slot */ - m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; - } - else - { - /* Installation authorized */ - e_ret_status = SFU_SUCCESS; - } - } - else - { - /* The installation is forbidden */ - TRACE("\r\n Anti-rollback: candidate version(%d) rejected | current version(%d) , min.version(%d) !", - p_x_fw_raw_header->FwVersion, curVer, SFU_FW_VERSION_START_NUM); - m_LoaderStatus = SFU_LOADER_ERR_FW_VERSION; - } - - - /* - * Control of version and length is done twice to avoid basic hardware attack - * This more important for the 1 image configuration as the installation is done during the download procedure - * For the 2 images configuration anti-rollback will be checked again during installation process - */ - if (SFU_IMG_CheckFwVersion(curVer, p_x_fw_raw_header->FwVersion) == SFU_SUCCESS) - { - /* Anti-rollback check pass */ -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n Anti-rollback: candidate version(%d) accepted | current version(%d) , min.version(%d) !", - p_x_fw_raw_header->FwVersion, curVer, SFU_FW_VERSION_START_NUM); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - - /* - * Check length : Let's make sure the Firmware image can be written in the destination slot. - */ - if (p_x_fw_raw_header->FwSize > (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) - { - /* The firmware cannot be written in dwl slot */ - m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; - } - else - { - /* Installation authorized */ - e_ret_status = SFU_SUCCESS; - } - } - else - { - /* The installation is forbidden */ - TRACE("\r\n Anti-rollback: candidate version(%d) rejected | current version(%d) , min.version(%d) !", - p_x_fw_raw_header->FwVersion, curVer, SFU_FW_VERSION_START_NUM); - m_LoaderStatus = SFU_LOADER_ERR_FW_VERSION; - } - } - else - { - /* Header authentication failure */ - m_LoaderStatus = SFU_LOADER_ERR_AUTH_FAILED; - } - - return e_ret_status; -} - -#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_loader.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_loader.h deleted file mode 100644 index e74ce1d3..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_loader.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_loader.h - * @author MCD Application Team - * @brief This file contains definitions for Secure Firmware Update local - * loader. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_LOADER_H -#define SFU_LOADER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "se_def.h" -#include "sfu_def.h" -#include "sfu_new_image.h" - -/* Exported types ------------------------------------------------------------*/ -/** - * @brief SFU_LOADER Status Type Definition - */ -typedef enum -{ - SFU_LOADER_OK = 0x00U, - SFU_LOADER_ERR_COM = 0x01U, - SFU_LOADER_ERR_AUTH_FAILED = 0x02U, - SFU_LOADER_ERR_FW_LENGTH = 0x03U, - SFU_LOADER_ERR_FW_VERSION = 0x04U, - SFU_LOADER_ERR_FLASH = 0x05U, - SFU_LOADER_ERR_CRYPTO = 0x06U -} SFU_LOADER_StatusTypeDef; - -/* Exported functions ------------------------------------------------------- */ -SFU_ErrorStatus SFU_LOADER_Init(void); -SFU_ErrorStatus SFU_LOADER_DeInit(void); -SFU_ErrorStatus SFU_LOADER_DownloadNewUserFw(SFU_LOADER_StatusTypeDef *peSFU_LOADER_Status, uint32_t *p_DwlSlot, - uint32_t *p_Size); - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_LOADER_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_test.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_test.c deleted file mode 100644 index b98a72e8..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_test.c +++ /dev/null @@ -1,332 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_test.c - * @author MCD Application Team - * @brief Test Protections module. - * This file provides set of firmware functions to manage Test Protections - * functionalities. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "sfu_test.h" -#include "main.h" -#include "sfu_trace.h" -#include "sfu_low_level_flash_int.h" -#include "sfu_low_level_security.h" -#include "sfu_low_level.h" -#include "string.h" /* required for strncmp */ - -#if defined(SFU_TEST_PROTECTION) - -extern RTC_HandleTypeDef RtcHandle; - -/* Private defines -----------------------------------------------------------*/ - -/* Automatic tests : list of tests (Address, Message, Operation */ -/* Flash programming by 64 bits */ -#define SHIFT_FLASH_WRITE (8U-1U) - -/* Private variables ---------------------------------------------------------*/ -static ProtectionTest_t aProtectTests[] = -{ -#ifdef SFU_MPU_PROTECT_ENABLE - {SFU_RAM_BASE, "MPU SRAM1 start add", TEST_EXECUTE}, - {SFU_RAM_END - 3U, "MPU SRAM1 end add", TEST_EXECUTE}, /* -3 : previous 32 bits for execute test */ - {PERIPH_BASE, "Peripheral base add", TEST_EXECUTE}, - {((uint32_t)0x5FFFFFFF - 3U), "Peripheral end address", TEST_EXECUTE}, /* -3 : previous 32 bits for execute test */ - /* READ_FLASH is possible as we are privileged when there is no MPU isolation but WRITE_FLASH must fail */ - {INTVECT_START, "Init. Vector", TEST_WRITE_FLASH}, - {SLOT_ACTIVE_1_START, "MPU code active slot1 begin add", TEST_EXECUTE}, - {SLOT_ACTIVE_1_END - 3U, "MPU code active1 slot end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ - {SLOT_ACTIVE_2_START, "MPU code active slot2 begin add", TEST_EXECUTE}, - {SLOT_ACTIVE_2_END - 3U, "MPU code active slot2 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ - {SLOT_ACTIVE_3_START, "MPU code active slot3 begin add", TEST_EXECUTE}, - {SLOT_ACTIVE_3_END - 3U, "MPU code active slot3 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ -#endif /* SFU_MPU_PROTECT_ENABLE */ -#ifdef SFU_WRP_PROTECT_ENABLE - {INTVECT_START, "WRP start add", TEST_WRITE_FLASH}, - {SFU_ROM_ADDR_END - SHIFT_FLASH_WRITE, "WRP end add", TEST_WRITE_FLASH}, /* -7 : alignment for 64bits writing test */ - {SB_REGION_ROM_START, "WRP internal (SB) add", TEST_ERASE_FLASH}, -#endif /* SFU_WRP_PROTECT_ENABLE */ -#ifdef SFU_PCROP_PROTECT_ENABLE - {SE_KEY_REGION_ROM_START, "PCROP start add", TEST_WRITE_FLASH}, - {SE_KEY_REGION_ROM_END - SHIFT_FLASH_WRITE, "PCROP end add", TEST_WRITE_FLASH}, /* -7 : alignment for 64bits - writing test */ - {SE_KEY_REGION_ROM_START, "PCROP start add", TEST_READ_FLASH}, - {SE_KEY_REGION_ROM_END, "PCROP end add", TEST_READ_FLASH}, -#endif /* SFU_PCROP_PROTECT_ENABLE */ -#if defined(TEST_ISOLATION) - {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_WRITE_FLASH}, /* WRP protection applies */ - {SE_CODE_REGION_ROM_END - SHIFT_FLASH_WRITE, "Isolated code end add", TEST_WRITE_FLASH},/* -7 : alignment for - 64bits writing test + WRP protection applies */ - {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_READ_FLASH}, - {SE_CODE_REGION_ROM_END, "Isolated code end add", TEST_READ_FLASH}, - {SE_STARTUP_REGION_ROM_START + 1U, "Isolated startup add", TEST_EXECUTE}, /* +1 : contains the SE startup code - that initializes all the variables in the binary. */ - {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_EXECUTE}, - {SE_CODE_REGION_ROM_END - 3U, "Isolated code end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ - {SE_REGION_RAM_START, "Isolated Vdata add", TEST_WRITE_RAM}, - {SE_REGION_RAM_END - 3U, "Isolated Vdata add", TEST_WRITE_RAM}, /* -3 : alignment for 32bits writing test */ - {SE_REGION_RAM_START, "Isolated Vdata add", TEST_READ_RAM}, - {SE_REGION_RAM_END, "Isolated Vdata add", TEST_READ_RAM}, - {SE_REGION_RAM_START, "Isolated Vdata add", TEST_EXECUTE}, - {SE_REGION_RAM_END - 3U, "Isolated Vdata add", TEST_EXECUTE}, /* -3 : alignment for 32bits writing test */ - {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, - /* -8 : previous 64 bits for writing test */ - {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits - for reading test */ - {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits - for execute test */ - {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, - /* -8 : previous 64 bits for writing test */ - {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits - for reading test */ - {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits - for execute test */ - {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, - /* -8 : previous 64 bits for writing test */ - {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits - for reading test */ - {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits - for execute test */ -#endif /* TEST_ISOLATION */ -#ifdef SFU_MPU_PROTECT_ENABLE - /* Testing the MPU protection of the OBs */ - /* - * WL55JC - * 0x1FFF 7800 Reserved user option bytes & RDP (USER & RDP) - * 0x1FFF 7818 Reserved Write protection 1A - * 0x1FFF 7820 Reserved Write protection 1B - * 0x1FFF 7870 User option bytes (USER) - * 0x1FFF 7878 User option bytes (USER) - */ - {(uint32_t)0x1FFF7800, "OBs @ 0x1FFFC000", TEST_WRITE_FLASH}, - {(uint32_t)0x1FFF7818, "OBs @ 0x1FFFC008", TEST_WRITE_FLASH}, - {(uint32_t)0x1FFF7820, "OBs @ 0x1FFFC008", TEST_WRITE_FLASH}, - {(uint32_t)0x1FFF7870, "OBs @ 0x1FFFC008", TEST_WRITE_FLASH}, - {(uint32_t)0x1FFF7878, "OBs @ 0x1FFFC008", TEST_WRITE_FLASH}, -#endif /* SFU_MPU_PROTECT_ENABLE */ - {0xAAAAAAAA, "Execution successful", TEST_END}, -}; - - -/* Automatic test : list of operation */ -uint8_t aTestOperation[][20] = -{ - "write 8 bytes", - "read 1 byte", - "erase 512 bytes", - "write 4 bytes", - "read 1 byte", - "execute", - "end" -}; - -/* Private function prototypes -----------------------------------------------*/ -static void SFU_TEST_Protection(void); - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief Automatic test of PCROP/WRP/FWALL/MPU protections - * @param None. - * @retval None. - */ -static void SFU_TEST_Protection(void) -{ - uint32_t test_idx; - uint32_t flashErrCode = 0; - uint64_t pattern = 0U; - uint32_t page_error = 0U; - FLASH_EraseInitTypeDef p_erase_init; - TestStatus status = TEST_IN_PROGRESS; - __IO uint8_t tmp; - void (*func)(void); - - /* - * Now checking the security - * We will try to access protected @ and run protected code. - * Each time a a flash error will be raised or a reset will be generated by IP protection. - * At next boot we read the backup register to check the next @ until all addresses have been verified. - * WatchDog should be disabled : while(1) loop in case HardFault when trying to execute code @ address protected by - * FWALL/Code Isolation - */ - - do - { - /* slow down execution */ - HAL_Delay(100); - - /* Increment test number for next execution */ - test_idx = HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR1); - HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, (test_idx + 1)); - printf("\r\n= [TEST] %s @ %s %08x", aTestOperation[aProtectTests[test_idx].type], aProtectTests[test_idx].msg, - aProtectTests[test_idx].address); - - /* Remove test for slots not configured (taking into accounbt SFU_IMG_IMAGE_OFFSET) */ - if ((aProtectTests[test_idx].address != 0U) && (aProtectTests[test_idx].address < 0xFFFFFF00U) - && (aProtectTests[test_idx].address > 0x00000FFFU)) - { - switch (aProtectTests[test_idx].type) - { - /* Trying to write 64bits in FLASH : WRP flag is set for WRP or PCROP protected area - or reset generated if under FWALL or MPU protection */ - case TEST_WRITE_FLASH : - HAL_FLASH_Unlock(); - HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, aProtectTests[test_idx].address, pattern); - HAL_FLASH_Lock(); - flashErrCode = HAL_FLASH_GetError(); - printf("\r\nflash error code: %x", flashErrCode); - if ((flashErrCode & HAL_FLASH_ERROR_WRP) == 0U) - { - status = TEST_ERROR; - } - - /* - * OBs protection test: MPU generates a MEMORY FAULT and a RESET - * So the test is FAILED if we reach this line - */ - if (0 == strncmp("OBs @", (const char *)aProtectTests[test_idx].msg, 5)) - { - status = TEST_ERROR; - } - /* else not an OB protection test so probably not an error */ - break; - - /* Trying to read in FLASH : RDP set in case of PCROP protected area - or reset generated if under FWALL or MPU protection */ - case TEST_READ_FLASH : - tmp = *(uint8_t *)(aProtectTests[test_idx].address); - HAL_Delay(1); /* ensure Flag is set */ - /* - * When Isolation activated : RESET should be generated - * So the test is FAILED if we reach this line - */ - if (0 == strncmp("Isolated", (const char *)aProtectTests[test_idx].msg, 8)) - { - status = TEST_ERROR; - } - - break; - - /* Trying to erase 512 bytes in FLASH : WRP flag set for WRP or PCROP protected area - or reset generated if under FWALL or MPU protection */ - case TEST_ERASE_FLASH : - HAL_FLASH_Unlock(); - p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; - p_erase_init.Page = SFU_LL_FLASH_GetPage(aProtectTests[test_idx].address); - p_erase_init.NbPages = 1; - HAL_FLASHEx_Erase(&p_erase_init, &page_error); - HAL_FLASH_Lock(); - if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) == 0U) - { - status = TEST_ERROR; - } - break; - - /* Trying to write in RAM : reset generated if under FWALL or MPU protection */ - case TEST_WRITE_RAM : - *(uint32_t *)aProtectTests[test_idx].address = 0x00000000; - status = TEST_ERROR; - break; - - /* Trying to read in RAM : reset generated if under FWALL or MPU protection */ - case TEST_READ_RAM : - tmp = *(uint8_t *)aProtectTests[test_idx].address; - printf(" value : %d ", tmp); - status = TEST_ERROR; - break; - - /* Tryning to execute code : reset generated if under FWALL or MPU protection */ - case TEST_EXECUTE : - func = (void(*)(void))(aProtectTests[test_idx].address); - func(); - status = TEST_ERROR; - break; - - /* End of execution */ - case TEST_END : - status = TEST_COMPLETED; - break; - - default : - break; - } - } - } while (status == TEST_IN_PROGRESS) ; - - if (status == TEST_ERROR) - { - SFU_TEST_Error(); - } - else if (status == TEST_COMPLETED) - { - /* reset for next run (need a RESET of the platform to restart a session) */ - printf("\b\b\b\b\b\b\b\b"); - printf("\r\nYou can RESET the platform to restart the tests.\r\n"); - HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_DONE); /* no more test in progress */ - } -} - -/** - * @brief Initialization of backup register and start test - * @param None. - * @retval None. - */ -void SFU_TEST_Init(void) -{ - /* Use register DR0 to know which if the test sequence is in progress or done */ - /* Use register DR1 to know which test to run after a reset */ - - if (MAGIC_TEST_DONE == HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0)) /* Test done */ - { - return; - } - else if (MAGIC_TEST_INIT != HAL_RTCEx_BKUPRead(&RtcHandle, - RTC_BKP_DR0)) /* Test not done nor in progress: Init magic (DR0) and - reset test index (DR1) */ - { - HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_INIT); - HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, 0x0000); - } - - /* Start test */ - SFU_TEST_Protection(); -} - -/** - * @brief Reset backup register to be able to execute a new test sequence - * @param None. - * @retval None. - */ -void SFU_TEST_Reset(void) -{ - HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_INIT); - HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, 0x0000); -} - -/** - * @brief Error detected during test sequence - * @param None. - * @retval None. - */ -void SFU_TEST_Error(void) -{ - printf(" ===> KO!!!!!"); - HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_DONE); -} - -#endif /* SFU_TEST_PROTECTION */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_trace.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_trace.h deleted file mode 100644 index 41b6e137..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_trace.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_trace.h - * @author MCD Application Team - * @brief This file contains definitions for SFU_TRACE functionalities. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_TRACE_H -#define SFU_TRACE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "app_sfu.h" -#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) -#include "sfu_com_trace.h" -#endif /* defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) */ - -/* External variables --------------------------------------------------------*/ -/** - * This variable indicates if at boot-up the FW presence check has already been performed or not: - * \li It is reset when the FW status has already been checked once and no FW is present - * \li (see @ref SFU_BOOT_SM_CheckUserFwStatus) - * \li It is used to display some messages only once in the teraterm console - * \li It is used to determine if the user button must be pressed before waiting for a local download to start - * \li This is used at LocalDownload and CheckUserFwStatus stages. - */ -extern uint8_t initialDeviceStatusCheck; /* used also in sfu_fwimg_swap.c */ - -/* Exported macros -----------------------------------------------------------*/ -#ifdef SFU_DEBUG_MODE -#define TRACE_IRQ(pbuffer) (void) SFU_COM_Serial_PutString(pbuffer); /* Printf is not used inside interrupt to avoid faults. - printf is not rieentrant */ -#define TRACE (void) printf -#else -#define TRACE(...) -#define TRACE_IRQ(pbuffer) -#endif /* SFU_DEBUG_MODE */ - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_TRACE_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level.c deleted file mode 100644 index 0bf6f3bd..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level.c +++ /dev/null @@ -1,528 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level.c - * @author MCD Application Team - * @brief SFU Low Level Interface module - * This file provides set of firmware functions to manage SFU low level - * interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_low_level.h" -#include "sfu_trace.h" - -#ifndef SFU_TAMPER_PROTECT_ENABLE -extern RTC_HandleTypeDef RtcHandle; -#endif /* SFU_TAMPER_PROTECT_ENABLE */ - -/* Private variables ---------------------------------------------------------*/ -static UART_HandleTypeDef UartHandle; -static CRC_HandleTypeDef CrcHandle; - -/* Private function prototypes -----------------------------------------------*/ -static void SFU_LL_Error_Handler(void); - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief Initialize SFU Interface. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_Init(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Initialize CRC */ - e_ret_status = SFU_LL_CRC_Init(); - - return e_ret_status; -} - -/** - * @brief DeInitialize SFU Interface. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_DeInit(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* ADD SRC CODE HERE - ... - */ - return e_ret_status; -} - -/** - * @brief SFU IF CRC Init. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_CRC_Init(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Configure the peripheral clock */ - __HAL_RCC_CRC_CLK_ENABLE(); - - - /* Configure CRC with default polynomial - standard configuration */ - e_ret_status = SFU_LL_CRC_Config(SFU_CRC_CONFIG_DEFAULT); - - return e_ret_status; -} - -/** - * @brief SFU IF CRC Configuration. - * @param eCRCConfg: SFU_CRC_ConfigTypeDef. - * This parameter can be a value of @ref SFU_CRC_ConfigTypeDef. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_CRC_Config(SFU_CRC_ConfigTypeDef eCRCConfg) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - - /* Check the parameters */ - assert_param(IS_SFU_CRC_CONF(eCRCConfg)); - - /* Switch to the selected configuration */ - CrcHandle.Instance = CRC; - - /* The input data are not inverted */ - CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; - - /* The output data are not inverted */ - CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; - - switch (eCRCConfg) - { - case SFU_CRC_CONFIG_DEFAULT: - /* The Default polynomial is used */ - CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; - /* The default init value is used */ - CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; - /* The input data are 32-bit long words */ - CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS; - /* Valid parameter*/ - e_ret_status = SFU_SUCCESS; - break; - - case SFU_CRC_CONFIG_16BIT: - /* The CRC-16-CCIT polynomial is used */ - CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; - CrcHandle.Init.GeneratingPolynomial = 0x1021U; - CrcHandle.Init.CRCLength = CRC_POLYLENGTH_16B; - /* The zero init value is used */ - CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; - CrcHandle.Init.InitValue = 0U; - /* The input data are 8-bit long */ - CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; - /* Valid parameter*/ - e_ret_status = SFU_SUCCESS; - break; - - default: - /* Invalid parameter */ - e_ret_status = SFU_ERROR; - break; - } - - /* Proceed to CRC Init (Correct Parameters) */ - if (e_ret_status == SFU_SUCCESS) - { - if (HAL_CRC_Init(&CrcHandle) != HAL_OK) - { - e_ret_status = SFU_ERROR; - } - } - - return e_ret_status; -} - - -/** - * @brief SFU IF CRC Calculate. - * @param pBuffer: pointer to data buffer. - * @param BufferLength: buffer length in bytes. - * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) - */ -uint32_t SFU_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t BufferLength) -{ - return HAL_CRC_Calculate(&CrcHandle, pBuffer, BufferLength); -} - -/** - * @brief SFU UART Init. - * @param None - * @retval status of the Init operation - * SFU_ERROR : if the Init operation failed. - * SFU_SUCCESS : if the Init operation is successfully performed. - */ -SFU_ErrorStatus SFU_LL_UART_Init(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/ - /* USART configured as follow: - - BaudRate = 115200 baud - - Word Length = 8 Bits - - One Stop Bit - - No parity - - Hardware flow control disabled (RTS and CTS signals) - - Receive and transmit enabled - */ - UartHandle.Instance = SFU_UART; - UartHandle.Init.BaudRate = 115200U; - UartHandle.Init.WordLength = UART_WORDLENGTH_8B; - UartHandle.Init.StopBits = UART_STOPBITS_1; - UartHandle.Init.Parity = UART_PARITY_NONE; - UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; - UartHandle.Init.Mode = UART_MODE_RX | UART_MODE_TX; - UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; - UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; - if (HAL_UART_Init(&UartHandle) == HAL_OK) - { - e_ret_status = SFU_SUCCESS; - } - - return e_ret_status; - -} - -/** - * @brief SFU IF UART DeInit. - * @param None - * @retval status of the Init operation - * SFU_ERROR : if the Init operation failed. - * SFU_SUCCESS : if the Init operation is successfully performed. - */ -SFU_ErrorStatus SFU_LL_UART_DeInit(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* - * ADD SRC CODE HERE - */ - - e_ret_status = SFU_SUCCESS; - - return e_ret_status; - -} - -/** - * @brief SFU IF Write data (send). - * @param pData: pointer to the 128bit data to write. - * @param DataLength: pointer to the 128bit data to write. - * @param pData: pointer to the 128bit data to write. - * @param Timeout: Timeout duration. - * @retval status of the write operation - * SFU_ERROR : if the write operation is not performed - * SFU_SUCCESS : if the write operation is successfully performed - */ -SFU_ErrorStatus SFU_LL_UART_Transmit(uint8_t *pData, uint16_t DataLength, uint32_t Timeout) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Check the pointers allocation */ - if (pData == NULL) - { - return SFU_ERROR; - } - - if (HAL_UART_Transmit(&UartHandle, (uint8_t *)pData, DataLength, Timeout) == HAL_OK) - { - e_ret_status = SFU_SUCCESS; - } - - return e_ret_status; -} - -/** - * @brief SFU IF Read data (receive). - * @param pData: pointer to the 128bit data where to store the received data. - * @param DataLength: the length of the data to be read in bytes. - * @param Timeout: Timeout duration. - * @retval status of the read operation - * SFU_ERROR : if the read operation is not performed - * SFU_SUCCESS : if the read operation is successfully performed - */ -SFU_ErrorStatus SFU_LL_UART_Receive(uint8_t *pData, uint16_t DataLength, uint32_t Timeout) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Check the pointers allocation */ - if (pData == NULL) - { - return SFU_ERROR; - } - - if (HAL_UART_Receive(&UartHandle, (uint8_t *)pData, DataLength, Timeout) == HAL_OK) - { - e_ret_status = SFU_SUCCESS; - } - - return e_ret_status; -} - -/** - * @brief SFU HAL IF Flush. - * @param None. - * @retval status of the operation. - */ -SFU_ErrorStatus SFU_LL_UART_Flush(void) -{ - /* Clean the input path */ - __HAL_UART_FLUSH_DRREGISTER(&UartHandle); - - return SFU_SUCCESS; -} - -#ifndef SFU_TAMPER_PROTECT_ENABLE -/** - * @brief SFU IF RTC Init. - * @param None - * @retval status of the Init operation - * SFU_ERROR : if the Init operation failed. - * SFU_SUCCESS : if the Init operation is successfully performed. - */ -SFU_ErrorStatus SFU_LL_RTC_Init(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Configure RTC prescaler and RTC data registers */ - /* RTC configured as follows: - - Hour Format = Format 24 - - Asynch Prediv = Value according to source clock - - Synch Prediv = Value according to source clock - - OutPut = Output Disable - - OutPutPolarity = High Polarity - - OutPutType = Open Drain */ - RtcHandle.Instance = RTC; - RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; - RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; - RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; - RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; - RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; - RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; - - if (HAL_RTC_Init(&RtcHandle) == HAL_OK) - { - e_ret_status = SFU_SUCCESS; - } - - return e_ret_status; -} - -/** - * @brief SFU IF RTC DeInit. - * @param None - * @retval status of the Init operation - * SFU_ERROR : if the Init operation failed. - * SFU_SUCCESS : if the Init operation is successfully performed. - */ -SFU_ErrorStatus SFU_LL_RTC_DeInit(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* - * ADD SRC CODE HERE - */ - - e_ret_status = SFU_SUCCESS; - - return e_ret_status; - -} - -#endif /*SFU_TAMPER_PROTECT_ENABLE*/ - -/** - * @brief SFU IF RTC MSP Initialization - * This function configures the hardware resources used in this example - * @param hrtc: RTC handle pointer. - * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select - * the RTC clock source; in this case the Backup domain will be reset in - * order to modify the RTC Clock source, as consequence RTC registers (including - * the backup registers) and RCC_BDCR register are set to their reset values. - * @retval None - */ -void SFU_LL_RTC_MspInit(RTC_HandleTypeDef *hrtc) -{ - RCC_OscInitTypeDef RCC_OscInitStruct; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; - - UNUSED(hrtc); - /*-1- Enables access to the backup domain */ - /* To enable access on RTC registers */ - - HAL_PWR_EnableBkUpAccess(); - - /*-2- Configure LSE/LSI as RTC clock source */ -#ifdef RTC_CLOCK_SOURCE_LSE - - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - RCC_OscInitStruct.LSEState = RCC_LSE_ON; - RCC_OscInitStruct.LSIState = RCC_LSI_OFF; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - SFU_LL_Error_Handler(); - } - - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; - PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) - { - SFU_LL_Error_Handler(); - } -#elif defined (RTC_CLOCK_SOURCE_LSI) - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - RCC_OscInitStruct.LSIState = RCC_LSI_ON; - RCC_OscInitStruct.LSIDiv = LL_RCC_LSI_PREDIV_1; - RCC_OscInitStruct.LSEState = RCC_LSE_OFF; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) - { - SFU_LL_Error_Handler(); - } - - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; - PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) - { - SFU_LL_Error_Handler(); - } -#else -#error Please select the RTC Clock source inside the main.h file -#endif /*RTC_CLOCK_SOURCE_LSE*/ - - /*-3- Enable RTC peripheral Clocks */ - /* Enable RTC Clock */ - __HAL_RCC_RTC_ENABLE(); - - /* Enable RTC APB clock */ - __HAL_RCC_RTCAPB_CLK_ENABLE(); -#ifdef SFU_TAMPER_PROTECT_ENABLE - /*-4- Configure the NVIC for RTC Tamper */ - HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, 0x0FU, 0U); - HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); -#endif /* SFU_TAMPER_PROTECT_ENABLE */ -} - -/** - * @brief RTC MSP De-Initialization - * This function frees the hardware resources used in in SFU application: - * - Disable the Peripheral's clock - * @param hrtc: RTC handle pointer - * @retval None - */ -void SFU_LL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc) -{ - UNUSED(hrtc); - - __HAL_RCC_RTC_DISABLE(); - - /* Disable RTC APB clock */ - __HAL_RCC_RTCAPB_CLK_DISABLE(); -} - -/** - * @brief UART MSP Initialization - * This function configures the hardware resources used in SFU application. - * @param huart: UART handle pointer - * @retval None - */ -void SFU_LL_UART_MspInit(UART_HandleTypeDef *huart) -{ - - GPIO_InitTypeDef GPIO_InitStruct; - if (huart->Instance == SFU_UART) - { - /* Peripheral Clock Enable */ - SFU_UART_CLK_ENABLE(); - - /* GPIO Ports Clock Enable */ - SFU_UART_TX_GPIO_CLK_ENABLE(); - SFU_UART_RX_GPIO_CLK_ENABLE(); - - /*Configure GPIO pins : SFU_UART_TX_Pin */ - GPIO_InitStruct.Pin = SFU_UART_TX_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = SFU_UART_TX_AF; - HAL_GPIO_Init(SFU_UART_TX_GPIO_PORT, &GPIO_InitStruct); - - /*Configure GPIO pins : SFU_UART_RX_Pin */ - GPIO_InitStruct.Pin = SFU_UART_RX_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = SFU_UART_RX_AF; - HAL_GPIO_Init(SFU_UART_RX_GPIO_PORT, &GPIO_InitStruct); - - } - -} - -/** - * @brief UART MSP De-Initialization - * This function frees the hardware resources used in SFU application: - * - Disable the Peripheral's clock - * @param huart: UART handle pointer - * @retval None - */ -void SFU_LL_UART_MspDeInit(UART_HandleTypeDef *huart) -{ - - if (huart->Instance == SFU_UART) - { - /* Peripheral clock disable */ - SFU_UART_CLK_DISABLE(); - - /* GPIO DeInit*/ - HAL_GPIO_DeInit(SFU_UART_TX_GPIO_PORT, SFU_UART_TX_PIN); - HAL_GPIO_DeInit(SFU_UART_RX_GPIO_PORT, SFU_UART_RX_PIN); - - } - - -} - -/** - * @brief This function is executed in case of error occurrence. - * @param None - * @retval None - */ -static void SFU_LL_Error_Handler(void) -{ - /* - * ADD SRC CODE HERE - */ - - while (1 == 1) - { - ; - } -} - - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level.h deleted file mode 100644 index cc8860a4..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level.h - * @author MCD Application Team - * @brief This file contains definitions for Secure Firmware Update low level - * interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_LOW_LEVEL_H -#define SFU_LOW_LEVEL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_def.h" - -/* Exported types ------------------------------------------------------------*/ -/** - * @brief SFU CRC Configuration definition - */ -typedef enum -{ - SFU_CRC_CONFIG_NONE = 0U, /*!< None */ - SFU_CRC_CONFIG_DEFAULT, /*!< Default configuration */ - SFU_CRC_CONFIG_16BIT /*!< 16 bit configuration */ -} SFU_CRC_ConfigTypeDef; - -/* Exported constants --------------------------------------------------------*/ -#define SFU_UART USART2 -#define SFU_UART_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() -#define SFU_UART_CLK_DISABLE() __HAL_RCC_USART2_CLK_DISABLE() - -#define SFU_UART_TX_AF GPIO_AF7_USART2 -#define SFU_UART_TX_GPIO_PORT GPIOA -#define SFU_UART_TX_PIN GPIO_PIN_2 -#define SFU_UART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define SFU_UART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() - -#define SFU_UART_RX_AF GPIO_AF7_USART2 -#define SFU_UART_RX_GPIO_PORT GPIOA -#define SFU_UART_RX_PIN GPIO_PIN_3 -#define SFU_UART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define SFU_UART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() - -/* Uncomment to enable the adequate Clock Source */ -#define RTC_CLOCK_SOURCE_LSI -/*#define RTC_CLOCK_SOURCE_LSE*/ - -#ifdef RTC_CLOCK_SOURCE_LSI -#define RTC_ASYNCH_PREDIV 0x1FU -#define RTC_SYNCH_PREDIV 0x3FF -#endif /* RTC_CLOCK_SOURCE_LSI */ - -#ifdef RTC_CLOCK_SOURCE_LSE -#define RTC_ASYNCH_PREDIV 0x7FU -#define RTC_SYNCH_PREDIV 0x00FFU -#endif /* RTC_CLOCK_SOURCE_LSE */ - - -/* Exported macros -----------------------------------------------------------*/ -#define IS_SFU_CRC_CONF(CONF) (((CONF) == SFU_CRC_CONFIG_NONE) || \ - ((CONF) == SFU_CRC_CONFIG_DEFAULT) || \ - ((CONF) == SFU_CRC_CONFIG_16BIT)) - -/* Dummy memory access : avoid compilation issue with STM32_Secure_Engine middleware - but not meaningful for this product */ -#define SFU_LL_DummyAccess() \ - do{ \ - }while(0) - -/* Exported functions ------------------------------------------------------- */ -SFU_ErrorStatus SFU_LL_Init(void); -SFU_ErrorStatus SFU_LL_DeInit(void); - -SFU_ErrorStatus SFU_LL_CRC_Init(void); -SFU_ErrorStatus SFU_LL_CRC_Config(SFU_CRC_ConfigTypeDef eCRCConfg); -uint32_t SFU_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t BufferLength); - -SFU_ErrorStatus SFU_LL_UART_Init(void); -SFU_ErrorStatus SFU_LL_UART_DeInit(void); -SFU_ErrorStatus SFU_LL_UART_Transmit(uint8_t *pData, uint16_t DataLength, uint32_t Timeout); -SFU_ErrorStatus SFU_LL_UART_Receive(uint8_t *pData, uint16_t DataLength, uint32_t Timeout); -SFU_ErrorStatus SFU_LL_UART_Flush(void); - -#ifndef SFU_TAMPER_PROTECT_ENABLE -SFU_ErrorStatus SFU_LL_RTC_Init(void); -SFU_ErrorStatus SFU_LL_RTC_DeInit(void); -#endif /*SFU_TAMPER_PROTECT_ENABLE*/ - -void SFU_LL_RTC_MspInit(RTC_HandleTypeDef *hrtc); -void SFU_LL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc); -void SFU_LL_UART_MspInit(UART_HandleTypeDef *huart); -void SFU_LL_UART_MspDeInit(UART_HandleTypeDef *huart); - - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_LOW_LEVEL_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash.c deleted file mode 100644 index 2dbc00c7..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash.c +++ /dev/null @@ -1,150 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_flash.c - * @author MCD Application Team - * @brief SFU Flash Low Level Interface module - * This file provides set of firmware functions to manage SFU flash - * low level interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "sfu_low_level_flash_int.h" -#include "sfu_low_level_flash_ext.h" -#include "sfu_fwimg_regions.h" - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief Initialize internal and external flash interface (OSPI/QSPI) - * @param none - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_Init(void) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - - e_ret_status = SFU_LL_FLASH_INT_Init(); - if (e_ret_status == SFU_SUCCESS) - { - e_ret_status = SFU_LL_FLASH_EXT_Init(); - } - return e_ret_status; -} - -/** - * @brief Depending on start address, this function will call internal or external (OSPI/QSPI) flash driver - * @param pFlashStatus: SFU_FLASH Status pointer - * @param pStart: flash address to be erased - * @param Length: number of bytes - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) -{ - - /* Check Flash start address */ - if ((uint32_t) pStart < EXTERNAL_FLASH_ADDRESS) - { - return SFU_LL_FLASH_INT_Erase_Size(pFlashStatus, pStart, Length); - } - else - { - return SFU_LL_FLASH_EXT_Erase_Size(pFlashStatus, pStart, Length); - } -} - -/** - * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver - * @param pFlashStatus: FLASH_StatusTypeDef - * @param pDestination: flash address to write - * @param pSource: pointer on buffer with data to write - * @param Length: number of bytes - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, const uint8_t *pSource, - uint32_t Length) -{ - /* Check Flash destination address */ - if ((uint32_t) pDestination < EXTERNAL_FLASH_ADDRESS) - { - return SFU_LL_FLASH_INT_Write(pFlashStatus, pDestination, pSource, Length); - } - else - { - return SFU_LL_FLASH_EXT_Write(pFlashStatus, pDestination, pSource, Length); - } -} - -/** - * @brief Depending on source address, this function will call internal or external (OSPI/QSPI) flash driver - * @param pDestination: pointer on buffer to store data - * @param pSource: flash address to read - * @param Length: number of bytes - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) -{ - /* Check Flash source address */ - if ((uint32_t) pSource < EXTERNAL_FLASH_ADDRESS) - { - return SFU_LL_FLASH_INT_Read(pDestination, pSource, Length); - } - else - { - return SFU_LL_FLASH_EXT_Read(pDestination, pSource, Length); - } -} - -/** - * @brief This function configure the flash to be able to execute code - * @param Addr: flash address - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_Config_Exe(uint32_t SlotNumber) -{ - /* - * Internal flash : nothing to do - * External flash : configure memory mapped mode - */ - - /* Check Flash address */ - if (SlotStartAdd[SlotNumber] < EXTERNAL_FLASH_ADDRESS) - { - return SFU_SUCCESS; - } - else - { - return SFU_LL_FLASH_EXT_Config_Exe(SlotNumber); - } -} - -/** - * @brief Gets the page of a given address - * @param Addr: flash address - * @retval The page of a given address - */ -uint32_t SFU_LL_FLASH_GetPage(uint32_t Addr) -{ - /* Check Flash address */ - if (Addr < EXTERNAL_FLASH_ADDRESS) - { - return SFU_LL_FLASH_INT_GetPage(Addr); - } - else - { - return INVALID_PAGE; /* Page number is not used in SBSFU application for external flash */ - } -} - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash.h deleted file mode 100644 index a7b6aaca..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_flash.h - * @author MCD Application Team - * @brief This file contains definitions for Secure Firmware Update flash - * low level interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_LOW_LEVEL_FLASH_H -#define SFU_LOW_LEVEL_FLASH_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_def.h" - -/* Exported types ------------------------------------------------------------*/ -typedef enum -{ - SFU_FLASH_ERROR = 0U, /*!< Error Flash generic*/ - SFU_FLASH_ERR_HAL, /*!< Error Flash HAL init */ - SFU_FLASH_ERR_ERASE, /*!< Error Flash erase */ - SFU_FLASH_ERR_WRITING, /*!< Error writing data in Flash */ - SFU_FLASH_ERR_WRITINGCTRL, /*!< Error checking data written in Flash */ - SFU_FLASH_SUCCESS /*!< Flash Success */ -} SFU_FLASH_StatusTypeDef; - -/* Exported constants --------------------------------------------------------*/ -#define INVALID_SECTOR 0xFFFFFFFFU -#define INVALID_PAGE 0xFFFFFFFFU -#define INVALID_BANK 0xFFFFFFFFU - -/* Exported functions ------------------------------------------------------- */ -SFU_ErrorStatus SFU_LL_FLASH_Init(void); -SFU_ErrorStatus SFU_LL_FLASH_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, const uint8_t *pSource, - uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_Config_Exe(uint32_t SlotNumber); - -uint32_t SFU_LL_FLASH_GetPage(uint32_t Addr); - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_LOW_LEVEL_FLASH_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c deleted file mode 100644 index 2e4b5b65..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c +++ /dev/null @@ -1,73 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_flash_ext.c - * @author MCD Application Team - * @brief SFU Flash Low Level Interface module - * This file provides set of firmware functions to manage SFU external - * flash low level interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_low_level_flash_ext.h" -#include "sfu_low_level_security.h" - -/* Private defines -----------------------------------------------------------*/ -#define BLOC_64_KBYTES 0x10000U - -/* Functions Definition ------------------------------------------------------*/ - -/* No external flash available on this product - ==> return SFU_ERROR except for SFU_LL_FLASH_EXT_Init and SFU_LL_FLASH_EXT_Config_Exe which are called - systematically during startup phase */ - -SFU_ErrorStatus SFU_LL_FLASH_EXT_Init(void) -{ - return SFU_SUCCESS; -} - -SFU_ErrorStatus SFU_LL_FLASH_EXT_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) -{ - UNUSED(pFlashStatus); - UNUSED(pStart); - UNUSED(Length); - return SFU_ERROR; -} - -SFU_ErrorStatus SFU_LL_FLASH_EXT_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, const uint8_t *pSource, - uint32_t Length) -{ - UNUSED(pFlashStatus); - UNUSED(pDestination); - UNUSED(pSource); - UNUSED(Length); - return SFU_ERROR; -} - -SFU_ErrorStatus SFU_LL_FLASH_EXT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) -{ - UNUSED(pDestination); - UNUSED(pSource); - UNUSED(Length); - return SFU_ERROR; -} - -SFU_ErrorStatus SFU_LL_FLASH_EXT_Config_Exe(uint32_t SlotNumber) -{ - UNUSED(SlotNumber); - return SFU_SUCCESS; -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h deleted file mode 100644 index 2f900bb8..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_flash_ext.h - * @author MCD Application Team - * @brief This file contains definitions for Secure Firmware Update low level - * interface for external flash. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_LOW_LEVEL_FLASH_EXT_H -#define SFU_LOW_LEVEL_FLASH_EXT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "sfu_low_level_flash.h" -#include "main.h" -#include "sfu_def.h" - -/* Exported constants --------------------------------------------------------*/ -#define EXTERNAL_FLASH_ADDRESS 0x90000000U - -/* Exported functions ------------------------------------------------------- */ -SFU_ErrorStatus SFU_LL_FLASH_EXT_Init(void); -SFU_ErrorStatus SFU_LL_FLASH_EXT_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_EXT_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, const uint8_t *pSource, - uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_EXT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_EXT_Config_Exe(uint32_t SlotNumber); - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_LOW_LEVEL_FLASH_EXT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c deleted file mode 100644 index 85480f7a..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c +++ /dev/null @@ -1,445 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_flash_int.c - * @author MCD Application Team - * @brief SFU Flash Low Level Interface module - * This file provides set of firmware functions to manage SFU internal - * flash low level interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_low_level_flash_int.h" -#include "sfu_low_level_security.h" -#include "se_interface_bootloader.h" -#include "string.h" -#include "sfu_fsm_states.h" -#include "sfu_error.h" - -/* Private defines -----------------------------------------------------------*/ -#define NB_PAGE_SECTOR_PER_ERASE 2U /*!< Nb page erased per erase */ - -/* Private variables ---------------------------------------------------------*/ -static __IO uint32_t DoubleECC_Error_Counter = 0U; - - -static SFU_ErrorStatus SFU_LL_FLASH_INT_Clear_Error(void); - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief This function initialize the internal flash interface if required - * @param none - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_INT_Init(void) -{ - return SFU_SUCCESS; -} - -/** - * @brief This function does an erase of n (depends on Length) pages in user flash area - * @param pFlashStatus: SFU_FLASH Status pointer - * @param pStart: flash address to be erased - * @param Length: number of bytes - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_INT_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) -{ - uint32_t page_error = 0U; - uint32_t start = (uint32_t)pStart; - FLASH_EraseInitTypeDef p_erase_init; - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint32_t first_page; - uint32_t nb_pages; - uint32_t chunk_nb_pages; - uint32_t length = Length; - - /* Check the pointers allocation */ - if (pFlashStatus == NULL) - { - return SFU_ERROR; - } - - *pFlashStatus = SFU_FLASH_SUCCESS; - - /* Clear error flags raised during previous operation */ - e_ret_status = SFU_LL_FLASH_INT_Clear_Error(); - - if (e_ret_status == SFU_SUCCESS) - { - /* Unlock the Flash to enable the flash control register access *************/ - if (HAL_FLASH_Unlock() == HAL_OK) - { - first_page = SFU_LL_FLASH_INT_GetPage(start); - /* Get the number of pages to erase from 1st page */ - nb_pages = SFU_LL_FLASH_INT_GetPage(start + length - 1U) - first_page + 1U; - p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; - /* Erase flash per NB_PAGE_SECTOR_PER_ERASE to avoid watch-dog */ - do - { - chunk_nb_pages = (nb_pages >= NB_PAGE_SECTOR_PER_ERASE) ? NB_PAGE_SECTOR_PER_ERASE : nb_pages; - p_erase_init.Page = first_page; - p_erase_init.NbPages = chunk_nb_pages; - first_page += chunk_nb_pages; - nb_pages -= chunk_nb_pages; - if (HAL_FLASHEx_Erase(&p_erase_init, &page_error) != HAL_OK) - { - e_ret_status = SFU_ERROR; - *pFlashStatus = SFU_FLASH_ERR_ERASE; - } - SFU_LL_SECU_IWDG_Refresh(); /* calling this function which checks the compiler switch */ - } while (nb_pages > 0U); - /* Lock the Flash to disable the flash control register access (recommended - to protect the FLASH memory against possible unwanted operation) *********/ - if (HAL_FLASH_Lock() != HAL_OK) - { - e_ret_status = SFU_ERROR; - *pFlashStatus = SFU_FLASH_ERR_HAL; - } - } - else - { - *pFlashStatus = SFU_FLASH_ERR_HAL; - } - } - - return e_ret_status; -} - -/** - * @brief This function writes a data buffer in flash (data are 32-bit aligned). - * @note After writing data buffer, the flash content is checked. - * @param pFlashStatus: FLASH_StatusTypeDef - * @param pDestination: Start address for target location. It has to be 8 bytes aligned. - * @param pSource: pointer on buffer with data to write - * @param Length: Length of data buffer in bytes. It has to be 8 bytes aligned. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_INT_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, const uint8_t *pSource, - uint32_t Length) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint32_t i; - uint32_t inside_header = 0U; - uint32_t destination = (uint32_t)pDestination; - uint32_t source = (uint32_t)pSource; - - /* Check the pointers allocation */ - if ((pFlashStatus == NULL) || (pSource == NULL)) - { - return SFU_ERROR; - } - - /* Is destination area inside 1 of the firmware image headers ? */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - if ((destination >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && - ((destination + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) - { - inside_header = 1U; - } - } - - /* Destination area part of 1 of the firmware image headers : - writing operation should be executed inside secure environment */ - if ((inside_header == 1U) && (Length != 0U)) - { - /* SE Access */ - SE_StatusTypeDef se_status; - SE_ErrorStatus se_ret_status = SE_SFU_IMG_Write(&se_status, (uint8_t *)destination, pSource, Length); - if (se_ret_status == SE_SUCCESS) - { - e_ret_status = SFU_SUCCESS; - *pFlashStatus = SFU_FLASH_SUCCESS; - } - else - { - e_ret_status = SFU_ERROR; - *pFlashStatus = SFU_FLASH_ERROR; - } - } - /* Writing operation executed by SBSFU */ - else - { - *pFlashStatus = SFU_FLASH_ERROR; - - /* Clear error flags raised during previous operation */ - e_ret_status = SFU_LL_FLASH_INT_Clear_Error(); - - if (e_ret_status == SFU_SUCCESS) - { - /* Unlock the Flash to enable the flash control register access *************/ - if (HAL_FLASH_Unlock() != HAL_OK) - { - *pFlashStatus = SFU_FLASH_ERR_HAL; - - } - else - { - /* DataLength must be a multiple of 64 bit */ - for (i = 0U; (i < Length) && (e_ret_status == SFU_SUCCESS); i += sizeof(SFU_LL_FLASH_write_t)) - { - *pFlashStatus = SFU_FLASH_ERROR; - - /* Device voltage range supposed to be [2.7V to 3.6V], the operation will - be done by word */ - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, destination, *((uint64_t *)(source + i))) - == HAL_OK) - { - /* Check the written value */ - if (*(uint64_t *)destination != *(uint64_t *)(source + i)) - { - /* Flash content doesn't match SRAM content */ - *pFlashStatus = SFU_FLASH_ERR_WRITINGCTRL; - e_ret_status = SFU_ERROR; - } - else - { - /* Increment FLASH Destination address */ - destination = destination + sizeof(SFU_LL_FLASH_write_t); - e_ret_status = SFU_SUCCESS; - *pFlashStatus = SFU_FLASH_SUCCESS; - } - } - else - { - /* Error occurred while writing data in Flash memory */ - *pFlashStatus = SFU_FLASH_ERR_WRITING; - e_ret_status = SFU_ERROR; - } - } - /* Lock the Flash to disable the flash control register access (recommended - to protect the FLASH memory against possible unwanted operation) */ - if (HAL_FLASH_Lock() != HAL_OK) - { - e_ret_status = SFU_ERROR; - *pFlashStatus = SFU_FLASH_ERR_HAL; - } - } - } - } - return e_ret_status; -} - -/** - * @brief This function reads flash - * @param pDestination: Start address for target location - * @param pSource: flash address to read - * @param Length: number of bytes - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_FLASH_INT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - SE_ErrorStatus se_ret_status; - SE_StatusTypeDef se_status; - uint32_t i; - uint32_t inside_header = 0U; - uint32_t source = (uint32_t)pSource; - - /* Is destination area inside 1 of the firmware image headers ? */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - if ((source >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && - ((source + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) - { - inside_header = 1U; - } - } - - /* Destination area part of 1 of the firmware image headers : - reading operation should be executed inside secure environment */ - if (inside_header == 1U) - { - /* SE Access */ - DoubleECC_Error_Counter = 0U; - se_ret_status = SE_SFU_IMG_Read(&se_status, pDestination, (uint8_t *)source, Length); - if ((se_ret_status == SE_SUCCESS) && (DoubleECC_Error_Counter == 0U)) - { - e_ret_status = SFU_SUCCESS; - } - DoubleECC_Error_Counter = 0U; - } - /* Reading operation executed by SBSFU */ - else - { - DoubleECC_Error_Counter = 0U; - (void) memcpy(pDestination, (uint8_t *)source, Length); - if (DoubleECC_Error_Counter == 0U) - { - e_ret_status = SFU_SUCCESS; - } - DoubleECC_Error_Counter = 0U; - } - return e_ret_status; -} - -/** - * @brief Gets the page of a given address - * @param Addr: flash address - * @retval The page of a given address - */ -uint32_t SFU_LL_FLASH_INT_GetPage(uint32_t Addr) -{ - uint32_t page; - - page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE; - - return page; -} - - - - -/** - * @brief Clear error flags raised during previous operation - * @param None. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -static SFU_ErrorStatus SFU_LL_FLASH_INT_Clear_Error(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Unlock the Program memory */ - if (HAL_FLASH_Unlock() == HAL_OK) - { - - /* Clear all FLASH flags */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); - - /* Unlock the Program memory */ - if (HAL_FLASH_Lock() == HAL_OK) - { - e_ret_status = SFU_SUCCESS; - } - } - - return e_ret_status; - -} - - -/** - * @brief Get Link Register value (LR) - * @param None. - * @retval LR Register value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_LR(void) -{ - register uint32_t result; - -#if defined ( __ICCARM__ ) || ( __GNUC__ ) - __ASM volatile("MOV %0, LR" : "=r"(result)); -#elif defined ( __CC_ARM ) - __ASM volatile("MOV result, __return_address()"); -#endif /* ( __ICCARM__ ) || ( __GNUC__ ) */ - - return result; -} - -/* - As this handler code relies on stack pointer position to manipulate the PC return value, it is important - not to use extra registers (on top of scratch registers), because it would change the stack pointer - position. Then compiler optimizations are customized to ensure that. -*/ -#if defined(__ICCARM__) -#pragma optimize=none -#elif defined(__CC_ARM) -#pragma O0 -#elif defined(__ARMCC_VERSION) -__attribute__((optnone)) -#elif defined(__GNUC__) -__attribute__((optimize("O1"))) -#endif /* __ICCARM__ */ -/** - * @brief NMI Handler present for handling Double ECC NMI interrupt - * @param None. - * @retvat void - */ -void NMI_Handler(void) -{ - uint32_t *p_sp; - uint32_t lr; - uint16_t opcode_msb; - - if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)) - { - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); - - /* Memorize error to ignore the read value */ - DoubleECC_Error_Counter++; - - lr = __get_LR(); - - /* Check EXC_RETURN value in LR to know which SP was used prior entering exception */ - if (((lr) & (0xFU)) == 0xDU) - { - /* interrupted code was using Process Stack Pointer */ - p_sp = (uint32_t *)__get_PSP(); - } - else - { - /* interrupted code was using Main Stack Pointer */ - p_sp = (uint32_t *)__get_MSP(); - } - - /* Test caller mode T bit from CPSR in stack */ - if ((*(p_sp + 7U) & (1U << xPSR_T_Pos)) != 0U) - { - /* Thumb mode. - Test PC in stack. - If bits [15:11] of the halfword being decoded take any of the following values, - the halfword is the first halfword of a 32-bit instruction: 0b11101, 0b11110, 0b11111. - Otherwise, the halfword is a 16-bit instruction. - */ - opcode_msb = (*(uint16_t *)(*(p_sp + 6) & 0xFFFFFFFEU) & 0xF800U); - if ((opcode_msb == 0xE800U) || (opcode_msb == 0xF000U) || (opcode_msb == 0xF800U)) - { - /* execute next instruction PC +4 */ - *(p_sp + 6U) += 4U; - } - else - { - /* execute next instruction PC +2 */ - *(p_sp + 6U) += 2U; - } - } - else - { - /* ARM mode execute next instruction PC +4 */ - *(p_sp + 6U) += 4U; - } - } - else - { - while (1 == 1) - { - ; - } - } -} - - -/** - * @brief HardFault Handler - * @param None. - * @retval None. - */ -void HardFault_Handler(void) -{ - SFU_BOOT_IrqExceptionHandler(SFU_EXCPT_HARD_FAULT); -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h deleted file mode 100644 index 221c183f..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_flash_int.h - * @author MCD Application Team - * @brief This file contains definitions for Secure Firmware Update low level - * interface for internal flash. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_LOW_LEVEL_FLASH_INT_H -#define SFU_LOW_LEVEL_FLASH_INT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "sfu_low_level_flash.h" -#include "main.h" -#include "sfu_def.h" - -/* Exported types ------------------------------------------------------------*/ -/** - * @brief Flash Write Access Constraints (size and alignment) - * - * For instance, on L4, it is only possible to program double word (2 x 32-bit data). - * See http://www.st.com/content/ccc/resource/technical/document/reference_manual/02/35/09/0c/4f/f7/40/03/DM00083560.pdf/files/DM00083560.pdf/jcr:content/translations/en.DM00083560.pdf - * - * @note This type is very important for the FWIMG module (see @ref SFU_IMG). - * \li This is the type to be used for an atomic write in FLASH: see @ref AtomicWrite. - * \li The size of this type changes the size of the TRAILER area at the end of dwl slot, - * as it is used to tag if a Firmware Image chunk has been swapped or not (see @ref SFU_IMG_CheckTrailerValid). - */ - -/* double-word is the default setting for most platforms */ -typedef uint64_t SFU_LL_FLASH_write_t; - -/* Exported constants --------------------------------------------------------*/ -/** - * Length of a MAGIC tag (32 bytes). - * This must be a multiple of @ref SFU_LL_FLASH_write_t with a minimum value of 32. - */ -#define MAGIC_LENGTH ((uint32_t)32U) - -/* External variables --------------------------------------------------------*/ -#define IS_ALIGNED(address) (0U == ((address) % FLASH_PAGE_SIZE)) - -/* Exported functions ------------------------------------------------------- */ -SFU_ErrorStatus SFU_LL_FLASH_INT_Init(void); -SFU_ErrorStatus SFU_LL_FLASH_INT_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_INT_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, const uint8_t *pSource, - uint32_t Length); -SFU_ErrorStatus SFU_LL_FLASH_INT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); -uint32_t SFU_LL_FLASH_INT_GetPage(uint32_t Addr); -void NMI_Handler(void); -void HardFault_Handler(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SFU_LOW_LEVEL_FLASH_INT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_security.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_security.c deleted file mode 100644 index d10c9f3f..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_security.c +++ /dev/null @@ -1,994 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_security.c - * @author MCD Application Team - * @brief SFU Security Low Level Interface module - * This file provides set of firmware functions to manage SFU security - * low level interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_low_level_security.h" -#include "sfu_low_level_flash_int.h" -#include "sfu_low_level.h" -#include "sfu_trace.h" -#include "sfu_boot.h" -#include "sfu_fsm_states.h" /* needed for sfu_error.h */ -#include "sfu_error.h" -#include "stm32wlxx_it.h" - -#ifndef SFU_WRP_PROTECT_ENABLE -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) -#warning "SFU_WRP_PROTECT_DISABLED" -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ -#endif /* SFU_WRP_PROTECT_ENABLE */ - -#ifndef SFU_RDP_PROTECT_ENABLE -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) -#warning "SFU_RDP_PROTECT_DISABLED" -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ -#endif /* SFU_RDP_PROTECT_ENABLE */ - - -#ifndef SFU_MPU_PROTECT_ENABLE -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) -#warning "SFU_MPU_PROTECT_DISABLED" -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ -#endif /* SFU_MPU_PROTECT_ENABLE */ - - -#ifndef SFU_TAMPER_PROTECT_ENABLE -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) -#warning "SFU_TAMPER_PROTECT_DISABLED" -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ -#endif /* SFU_TAMPER_PROTECT_ENABLE */ - -#ifndef SFU_DAP_PROTECT_ENABLE -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) -#warning "SFU_DAP_PROTECT_DISABLED" -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ -#endif /* SFU_DAP_PROTECT_ENABLE */ - -#ifndef SFU_DMA_PROTECT_ENABLE -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) -#warning "SFU_DMA_PROTECT_DISABLED" -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ -#endif /* SFU_DMA_PROTECT_ENABLE */ - -#ifndef SFU_IWDG_PROTECT_ENABLE -#if !defined(SECBOOT_DISABLE_SECURITY_IPS) -#warning "SFU_IWDG_PROTECT_DISABLED" -#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ -#endif /* SFU_IWDG_PROTECT_ENABLE */ - - -/* Private typedef -----------------------------------------------------------*/ -typedef enum -{ - SFU_FALSE = 0U, - SFU_TRUE = !SFU_FALSE -} SFU_BoolTypeDef; - -typedef struct -{ - uint8_t Number; /*!< Specifies the number of the region to protect. This parameter can be a - value of CORTEX_MPU_Region_Number */ - uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */ - uint8_t Size; /*!< Specifies the size of the region to protect. */ - uint8_t AccessPermission; /*!< Specifies the region access permission type. This parameter can be a - value of CORTEX_MPU_Region_Permission_Attributes */ - uint8_t DisableExec; /*!< Specifies the instruction access status. This parameter can be a value - of CORTEX_MPU_Instruction_Access */ - uint8_t SubRegionDisable; /*!< Specifies the sub region field (region is divided in 8 slices) when bit - is 1 region sub region is disabled */ -} SFU_MPU_InitTypeDef; - -typedef uint32_t SFU_ProtectionTypeDef; /*!< SFU HAL IF Protection Type Def*/ - -/* Private variables ---------------------------------------------------------*/ -#ifdef SFU_IWDG_PROTECT_ENABLE -static IWDG_HandleTypeDef IwdgHandle; - -#endif /* SFU_IWDG_PROTECT_ENABLE */ -#ifdef SFU_MPU_PROTECT_ENABLE -static SFU_MPU_InitTypeDef MpuAreas[] = - - { - { - MPU_REGION_NUMBER0, SFU_PROTECT_MPU_AREA_USER_START, SFU_PROTECT_MPU_AREA_USER_SIZE, - SFU_PROTECT_MPU_AREA_USER_PERM, SFU_PROTECT_MPU_AREA_USER_EXEC, SFU_PROTECT_MPU_AREA_USER_SREG - }, -{ - MPU_REGION_NUMBER1, SFU_PROTECT_MPU_AREA_SFUEN_START_0, SFU_PROTECT_MPU_AREA_SFUEN_SIZE_0, - SFU_PROTECT_MPU_AREA_SFUEN_PERM, SFU_PROTECT_MPU_AREA_SFUEN_EXEC, SFU_PROTECT_MPU_AREA_SFUEN_SREG_0 -}, -{ - MPU_REGION_NUMBER2, SFU_PROTECT_MPU_AREA_SFUEN_START_1, SFU_PROTECT_MPU_AREA_SFUEN_SIZE_1, - SFU_PROTECT_MPU_AREA_SFUEN_PERM, SFU_PROTECT_MPU_AREA_SFUEN_EXEC, SFU_PROTECT_MPU_AREA_SFUEN_SREG_1 -}, -{ - MPU_REGION_NUMBER3, SFU_PROTECT_MPU_AREA_VECT_START, SFU_PROTECT_MPU_AREA_VECT_SIZE, - SFU_PROTECT_MPU_AREA_VECT_PERM, SFU_PROTECT_MPU_AREA_VECT_EXEC, SFU_PROTECT_MPU_AREA_VECT_SREG -}, -{ - MPU_REGION_NUMBER4, SFU_PROTECT_MPU_AREA_OB_BANK1_START, SFU_PROTECT_MPU_AREA_OB_BANK1_SIZE, - SFU_PROTECT_MPU_AREA_OB_BANK1_PERM, SFU_PROTECT_MPU_AREA_OB_BANK1_EXEC, SFU_PROTECT_MPU_AREA_OB_BANK1_SREG -}, -{ - MPU_REGION_NUMBER5, SFU_PROTECT_MPU_AREA_PERIPH_START, SFU_PROTECT_MPU_AREA_PERIPH_SIZE, - SFU_PROTECT_MPU_AREA_PERIPH_PERM, SFU_PROTECT_MPU_AREA_PERIPH_EXEC, SFU_PROTECT_MPU_AREA_PERIPH_SREG -}, - }; -#endif /* SFU_MPU_PROTECT_ENABLE */ - -/* Private function prototypes -----------------------------------------------*/ -static SFU_ErrorStatus SFU_LL_SECU_CheckFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes); -static SFU_ErrorStatus SFU_LL_SECU_SetFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, - SFU_BoolTypeDef *pbIsProtectionToBeApplied); - -#ifdef SFU_RDP_PROTECT_ENABLE -static SFU_ErrorStatus SFU_LL_SECU_SetProtectionRDP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, - SFU_BoolTypeDef *pbIsProtectionToBeApplied); -#endif /*SFU_RDP_PROTECT_ENABLE*/ - -#ifdef SFU_WRP_PROTECT_ENABLE -static SFU_ErrorStatus SFU_LL_SECU_CheckProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes); -static SFU_ErrorStatus SFU_LL_SECU_SetProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, - SFU_BoolTypeDef *pbIsProtectionToBeApplied); -#endif /*SFU_WRP_PROTECT_ENABLE*/ - - - - -#ifdef SFU_IWDG_PROTECT_ENABLE -static SFU_ErrorStatus SFU_LL_SECU_SetProtectionIWDG(void); -#endif /*SFU_IWDG_PROTECT_ENABLE*/ - -#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE -static SFU_ErrorStatus SFU_LL_SECU_SetProtectionCLOCK_MONITOR(void); -#endif /*SFU_CLCK_MNTR_PROTECT_ENABLE*/ - -#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE -static SFU_ErrorStatus SFU_LL_SECU_SetProtectionTEMP_MONITOR(void); -#endif /*SFU_TEMP_MNTR_PROTECT_ENABLE*/ - - -/* Private function prototypes -----------------------------------------------*/ -/** - * @brief Check and if not applied apply the Static security protections to - * all the SfuEn Sections in Flash: RDP, WRP, PCRoP. Static security protections - * those protections not impacted by a Reset. They are set using the Option Bytes - * When the device is locked (RDP Level2), these protections cannot be changed anymore - * @param None - * @note By default, the best security protections are applied to the different - * flash sections in order to maximize the security level for the specific MCU. - * @retval uint32_t CRC (returned value is the combination of all the applied protections. - * If different from SFU_STD_PROTECTION_ALL, 1 or more protections cannot be applied) - */ -SFU_ErrorStatus SFU_LL_SECU_CheckApplyStaticProtections(void) -{ - FLASH_OBProgramInitTypeDef flash_option_bytes; - SFU_BoolTypeDef is_protection_to_be_applied = SFU_FALSE; - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - - /* Unlock the Flash to enable the flash control register access *************/ - (void) HAL_FLASH_Unlock(); - - /* Clear OPTVERR bit set on virgin samples */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); - - /* Unlock the Options Bytes *************************************************/ - (void) HAL_FLASH_OB_Unlock(); - - /* Get Option Bytes status for WRP AREA_A **********/ - flash_option_bytes.WRPArea = SFU_PROTECT_WRP_AREA_1; - (void) HAL_FLASHEx_OBGetConfig(&flash_option_bytes); - - /* Check/Apply RDP_Level 1. This is the minimum protection allowed */ - /* if RDP_Level 2 is already applied it's not possible to modify the OptionBytes anymore */ - if (flash_option_bytes.RDPLevel == OB_RDP_LEVEL_2) - { - /* Sanity check of the (enabled) static protections */ - if (SFU_LL_SECU_CheckFlashConfiguration(&flash_option_bytes) != SFU_SUCCESS) - { - TRACE("\r\n= [SBOOT] Flash configuration failed! Product blocked."); - /* Security issue : execution stopped ! */ - SFU_EXCPT_Security_Error(); - } - -#ifdef SFU_WRP_PROTECT_ENABLE - if (SFU_LL_SECU_CheckProtectionWRP(&flash_option_bytes) != SFU_SUCCESS) - { - TRACE("\r\n= [SBOOT] System Security Configuration failed! Product blocked."); - /* Security issue : execution stopped ! */ - SFU_EXCPT_Security_Error(); - } -#endif /* SFU_WRP_PROTECT_ENABLE */ - - - - /*RDP level 2 ==> Flow control by-passed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); - } - else - { - /* Check/Set Flash configuration *******************************************/ - if (e_ret_status == SFU_SUCCESS) - { - e_ret_status = SFU_LL_SECU_SetFlashConfiguration(&flash_option_bytes, &is_protection_to_be_applied); - } - - /* Check/Apply WRP ********************************************************/ -#ifdef SFU_WRP_PROTECT_ENABLE - if (e_ret_status == SFU_SUCCESS) - { - e_ret_status = SFU_LL_SECU_SetProtectionWRP(&flash_option_bytes, &is_protection_to_be_applied); - } -#endif /* SFU_WRP_PROTECT_ENABLE */ - - /* Check/Apply PCRoP ******************************************************/ - - - /* Check/Apply RDP : RDP-L2 should be done as last option bytes configuration */ -#ifdef SFU_RDP_PROTECT_ENABLE - if (e_ret_status == SFU_SUCCESS) - { - e_ret_status = SFU_LL_SECU_SetProtectionRDP(&flash_option_bytes, &is_protection_to_be_applied); - } -#endif /* SFU_RDP_PROTECT_ENABLE */ - - if (e_ret_status == SFU_SUCCESS) - { - if (is_protection_to_be_applied) - { - /* Generate System Reset to reload the new option byte values *************/ - /* WARNING: This means that if a protection can't be set, there will be a reset loop! */ - (void) HAL_FLASH_OB_Launch(); - } - } - } - - - /* Lock the Options Bytes ***************************************************/ - (void) HAL_FLASH_OB_Lock(); - - /* Lock the Flash to disable the flash control register access (recommended - to protect the FLASH memory against possible unwanted operation) *********/ - (void) HAL_FLASH_Lock(); - - /* If it was not possible to apply one of the above mandatory protections, the - Option bytes have not been reloaded. Return the error status in order for the - caller function to take the right actions */ - return e_ret_status; - -} - -/** - * @brief Apply Runtime security protections. - * Runtime security protections have to be re-configured at each Reset. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_CheckApplyRuntimeProtections(uint8_t uStep) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - SFU_ProtectionTypeDef runtime_protection = SFU_PROTECTIONS_NONE; - - /* Depending on compilation switches, prevent compilation warning */ - UNUSED(runtime_protection); - - -#ifdef SFU_MPU_PROTECT_ENABLE - if (SFU_LL_SECU_SetProtectionMPU() == SFU_SUCCESS) - { - runtime_protection |= SFU_RUNTIME_PROTECTION_MPU; - } - else - { - /* When a protection cannot be set then SFU_ERROR is returned */ - e_ret_status = SFU_ERROR; - } -#endif /* SFU_MPU_PROTECT_ENABLE */ - - - - /* Check/Apply disable DMAs ************************************************/ -#ifdef SFU_DMA_PROTECT_ENABLE - if (SFU_LL_SECU_SetProtectionDMA() == SFU_SUCCESS) - { - runtime_protection |= SFU_RUNTIME_PROTECTION_DMA; - } - else - { - /* When a protection cannot be set then SFU_ERROR is returned */ - e_ret_status = SFU_ERROR; - } -#endif /* SFU_DMA_PROTECT_ENABLE */ - - /* Check/Apply IWDG **************************************************/ -#ifdef SFU_IWDG_PROTECT_ENABLE - if (SFU_LL_SECU_SetProtectionIWDG() == SFU_SUCCESS) - { - runtime_protection |= SFU_RUNTIME_PROTECTION_IWDG; - } - else - { - /* When a protection cannot be set then SFU_ERROR is returned */ - e_ret_status = SFU_ERROR; - } -#endif /* SFU_IWDG_PROTECT_ENABLE */ - - /* Check/Apply DAP *********************************************************/ -#ifdef SFU_DAP_PROTECT_ENABLE - if (SFU_LL_SECU_SetProtectionDAP() == SFU_SUCCESS) - { - runtime_protection |= SFU_RUNTIME_PROTECTION_DAP; - } - else - { - /* When a protection cannot be set then SFU_ERROR is returned */ - e_ret_status = SFU_ERROR; - } -#else -#endif /* SFU_DAP_PROTECT_ENABLE */ - - /* Check/Apply ANTI_TAMPER *************************************************/ -#ifdef SFU_TAMPER_PROTECT_ENABLE - if (SFU_LL_SECU_SetProtectionANTI_TAMPER() == SFU_SUCCESS) - { - runtime_protection |= SFU_RUNTIME_PROTECTION_ANTI_TAMPER; - } - else - { - /* When a protection cannot be set then SFU_ERROR is returned */ - e_ret_status = SFU_ERROR; - } -#else -#ifdef SFU_TEST_PROTECTION - if (SFU_LL_RTC_Init() != SFU_SUCCESS) - { - e_ret_status = SFU_ERROR; - } -#endif /* SFU_TEST_PROTECTION */ -#endif /* SFU_TAMPER_PROTECT_ENABLE */ - /* Check/Apply CLOCK_MONITOR **********************************************/ -#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE - if (SFU_LL_SECU_SetProtectionCLOCK_MONITOR() == SFU_SUCCESS) - { - runtime_protection |= SFU_RUNTIME_PROTECTION_CLOCK_MONITOR; - } - else - { - /* When a protection cannot be set then SFU_ERROR is returned */ - e_ret_status = SFU_ERROR; - } -#endif /* SFU_CLCK_MNTR_PROTECT_ENABLE */ - - /* Check/Apply TEMP_MONITOR **********************************************/ -#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE - if (SFU_LL_SECU_SetProtectionTEMP_MONITOR() == SFU_SUCCESS) - { - runtime_protection |= SFU_RUNTIME_PROTECTION_TEMP_MONITOR; - } - else - { - /* When a protection cannot be set then SFU_ERROR is returned */ - e_ret_status = SFU_ERROR; - } -#endif /* SFU_TEMP_MNTR_PROTECT_ENABLE */ - -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE("\r\n= [SBOOT] RuntimeProtections: %x", runtime_protection); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - - return e_ret_status; -} - -/** - * @brief Return the reset source detected after a reboot. The related flag is reset - * at the end of this function. - * @param peResetpSourceId: to be filled with the detected source of reset - * @note In case of multiple reset sources this function return only one of them. - * It can be improved returning and managing a combination of them. - * @retval SFU_SUCCESS if successful, SFU_ERROR otherwise - */ -void SFU_LL_SECU_GetResetSources(SFU_RESET_IdTypeDef *peResetpSourceId) -{ - /* Check if the last reset has been generated from a Watchdog exception */ - if ((__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) || - (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)) - { - *peResetpSourceId = SFU_RESET_WDG_RESET; - - } - - - /* Check if the last reset has been generated from a Low Power reset */ - else if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) != RESET) - { - *peResetpSourceId = SFU_RESET_LOW_POWER; - - } - - /* Check if the last reset has been generated from a Software reset */ - else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) != RESET) - { - *peResetpSourceId = SFU_RESET_SW_RESET; - - } - /* Check if the last reset has been generated from an Option Byte Loader reset */ - else if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST) != RESET) - { - *peResetpSourceId = SFU_RESET_OB_LOADER; - } - /* Check if the last reset has been generated from a Hw pin reset */ - else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET) - { - *peResetpSourceId = SFU_RESET_HW_RESET; - - } - /* Unknown */ - else - { - *peResetpSourceId = SFU_RESET_UNKNOWN; - } -} - -/** - * @brief Clear the reset sources. This function should be called after the actions - * on the reset sources has been already taken. - * @param none - * @note none - * @retval none - */ -void SFU_LL_SECU_ClearResetSources() -{ - /* Clear reset flags */ - __HAL_RCC_CLEAR_RESET_FLAGS(); -} - -/** - * @brief Refresh Watchdog : reload counter - * This function must be called just before jumping to the UserFirmware - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_IWDG_Refresh(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - -#ifdef SFU_IWDG_PROTECT_ENABLE - /* Refresh IWDG: reload counter */ - if (HAL_IWDG_Refresh(&IwdgHandle) == HAL_OK) - { - e_ret_status = SFU_SUCCESS; - } -#else - e_ret_status = SFU_SUCCESS; -#endif /*SFU_IWDG_PROTECT_ENABLE*/ - - return e_ret_status; -} - -/** - * @brief Check Flash configuration. - * @param psFlashOptionBytes: pointer to the Option Bytes structure - * @retval SFU_ErrorStatus SFU_SUCCESS if Flash configuration is correct, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_CheckFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Check/Apply BOOT_LOCK ****************************************************/ - if ((psFlashOptionBytes->UserConfig & FLASH_OPTR_BOOT_LOCK) == OB_BOOT_LOCK_ENABLE) - { - e_ret_status = SFU_SUCCESS; - } - if (e_ret_status == SFU_SUCCESS) - { - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_UBE, FLOW_CTRL_UBE); - } - return e_ret_status; - -} - -/** - * @brief Set Flash configuration. - * @param psFlashOptionBytes: pointer to the Option Bytes structure - * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if - * this OptByte has to be modified and immediately reloaded. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, - SFU_BoolTypeDef *pbIsProtectionToBeApplied) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Check Flash configuration */ - if (SFU_LL_SECU_CheckFlashConfiguration(psFlashOptionBytes) == SFU_SUCCESS) - { - e_ret_status = SFU_SUCCESS; - } - else - { -#if defined(SECBOOT_OB_DEV_MODE) - psFlashOptionBytes->OptionType = OPTIONBYTE_USER; - psFlashOptionBytes->UserConfig &= ~OB_BOOT_LOCK_ENABLE; - psFlashOptionBytes->UserConfig |= OB_BOOT_LOCK_ENABLE; - if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) - { - *pbIsProtectionToBeApplied |= 1U; - e_ret_status = SFU_SUCCESS; - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_UBE, FLOW_CTRL_UBE); - } -#else - TRACE("\r\n= [SBOOT] Boot Configuration issue: booting Main flash through PA14-BOOT0 pin functionality cannot be guaranteed"); - /* Security issue : execution stopped ! */ - SFU_EXCPT_Security_Error(); -#endif /* SECBOOT_OB_DEV_MODE */ - } - - return e_ret_status; -} - -#ifdef SFU_RDP_PROTECT_ENABLE -/** - * @brief Apply the RDP protection - * @param psFlashOptionBytes: pointer to the Option Bytes structure - * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if - * this OptByte has to be modified and immediately reloaded. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionRDP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, - SFU_BoolTypeDef *pbIsProtectionToBeApplied) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Check/Apply RDP **********************************************************/ - /* Please consider that the suggested and most secure approach is to set the RDP_LEVEL_2 */ - if (psFlashOptionBytes->RDPLevel == SFU_PROTECT_RDP_LEVEL) - { - e_ret_status = SFU_SUCCESS; /*Protection already applied */ - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); - } - else - { -#if defined(SECBOOT_OB_DEV_MODE) -#if defined(SFU_FINAL_SECURE_LOCK_ENABLE) - TRACE("\r\n\t Applying RDP-2 Level. Product locked! You might need to unplug/plug the USB cable!"); -#else - TRACE("\r\n\t Applying RDP-1 Level. You might need to unplug/plug the USB cable!"); -#endif /* SFU_FINAL_SECURE_LOCK_ENABLE */ - psFlashOptionBytes->OptionType = OPTIONBYTE_RDP; - psFlashOptionBytes->RDPLevel = SFU_PROTECT_RDP_LEVEL; - if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) - { - *pbIsProtectionToBeApplied |= 1U; - e_ret_status = SFU_SUCCESS; - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); - } -#else - TRACE("\r\n= [SBOOT] System Security Configuration failed: RDP is incorrect. STOP!"); - /* Security issue : execution stopped ! */ - SFU_EXCPT_Security_Error(); -#endif /* SECBOOT_OB_DEV_MODE */ - } - return e_ret_status; -} -#endif /*SFU_RDP_PROTECT_ENABLE*/ - -#ifdef SFU_WRP_PROTECT_ENABLE -/** - * @brief Check the WRP protection to the specified Area. It includes the SFU Vector Table - * @param psFlashOptionBytes: pointer to the Option Bytes structure - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_CheckProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes) -{ - SFU_ErrorStatus e_ret_status = SFU_SUCCESS; - - /* Check WRP ****************************************************************/ - if ((psFlashOptionBytes->WRPStartOffset > SFU_PROTECT_WRP_PAGE_START_1) || - (psFlashOptionBytes->WRPEndOffset < SFU_PROTECT_WRP_PAGE_END_1)) - { - e_ret_status = SFU_ERROR; /*Protection not applied */ - } - if (e_ret_status == SFU_SUCCESS) - { - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_WRP, FLOW_CTRL_WRP); - } - return e_ret_status; -} - -/** - * @brief Apply the WRP protection to the specified Area. It includes the SFU Vector Table - * @param psFlashOptionBytes: pointer to the Option Bytes structure - * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if - * this OptByte has to be modified and immediately reloaded. - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, - SFU_BoolTypeDef *pbIsProtectionToBeApplied) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Check/Apply WRP **********************************************************/ - if (SFU_LL_SECU_CheckProtectionWRP(psFlashOptionBytes) == SFU_SUCCESS) - { - e_ret_status = SFU_SUCCESS; /*Protection already applied */ - } - else - { -#if defined(SECBOOT_OB_DEV_MODE) - psFlashOptionBytes->OptionType = OPTIONBYTE_WRP; - psFlashOptionBytes->WRPArea = SFU_PROTECT_WRP_AREA_1; - psFlashOptionBytes->WRPStartOffset = SFU_PROTECT_WRP_PAGE_START_1; - psFlashOptionBytes->WRPEndOffset = SFU_PROTECT_WRP_PAGE_END_1; - - if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) - { - *pbIsProtectionToBeApplied |= 1U; - e_ret_status = SFU_SUCCESS; - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_WRP, FLOW_CTRL_WRP); - } -#else - TRACE("\r\n= [SBOOT] System Security Configuration failed: WRP is incorrect. STOP!"); - /* Security issue : execution stopped ! */ - SFU_EXCPT_Security_Error(); -#endif /* SECBOOT_OB_DEV_MODE */ - } - - return e_ret_status; -} -#endif /*SFU_WRP_PROTECT_ENABLE*/ - -#ifdef SFU_MPU_PROTECT_ENABLE -/** - * @brief Apply MPU protection before executing UserApp - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU_UserApp(void) -{ - MPU_Region_InitTypeDef MPU_InitStruct; - - MPU_InitStruct.Enable = MPU_REGION_ENABLE; - MPU_InitStruct.Number = MPU_REGION_NUMBER6; - MPU_InitStruct.BaseAddress = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_START; - MPU_InitStruct.Size = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SIZE; - MPU_InitStruct.SubRegionDisable = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SREG; - MPU_InitStruct.AccessPermission = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_PERM; - MPU_InitStruct.DisableExec = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_EXEC; - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; - MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; - HAL_MPU_ConfigRegion(&MPU_InitStruct); - - - MPU_InitStruct.Enable = MPU_REGION_ENABLE; - MPU_InitStruct.Number = MPU_REGION_NUMBER7; - MPU_InitStruct.BaseAddress = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_START; - MPU_InitStruct.Size = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SIZE; - MPU_InitStruct.SubRegionDisable = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SREG; - MPU_InitStruct.AccessPermission = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_PERM; - MPU_InitStruct.DisableExec = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_EXEC; - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; - MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; - HAL_MPU_ConfigRegion(&MPU_InitStruct); - - - return SFU_SUCCESS; -} -#endif /* SFU_MPU_PROTECT_ENABLE */ - -#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) -/** - * @brief Apply MPU protection before executing Standalone loader - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU_StandaloneLoader(void) -{ - MPU_Region_InitTypeDef MPU_InitStruct; - - MPU_InitStruct.Enable = MPU_REGION_ENABLE; - MPU_InitStruct.Number = MPU_REGION_NUMBER6; - MPU_InitStruct.BaseAddress = LOADER_PROTECT_MPU_AREA_START; - MPU_InitStruct.Size = LOADER_PROTECT_MPU_AREA_SIZE; - MPU_InitStruct.SubRegionDisable = LOADER_PROTECT_MPU_AREA_SREG; - MPU_InitStruct.AccessPermission = LOADER_PROTECT_MPU_AREA_PERM; - MPU_InitStruct.DisableExec = LOADER_PROTECT_MPU_AREA_EXEC; - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; - MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; - HAL_MPU_ConfigRegion(&MPU_InitStruct); - - return SFU_SUCCESS; -} -#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ - -#ifdef SFU_MPU_PROTECT_ENABLE - -/** - * @brief Apply MPU protection - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - uint8_t mpu_region_num; /* id of the MPU region being configured */ - MPU_Region_InitTypeDef MPU_InitStruct; - - HAL_MPU_Disable(); - - for (mpu_region_num = 0U; mpu_region_num < (sizeof(MpuAreas) / sizeof(SFU_MPU_InitTypeDef)); mpu_region_num++) - { - MPU_InitStruct.Enable = MPU_REGION_ENABLE; - MPU_InitStruct.Number = MpuAreas[mpu_region_num].Number; - MPU_InitStruct.BaseAddress = MpuAreas[mpu_region_num].BaseAddress; - MPU_InitStruct.Size = MpuAreas[mpu_region_num].Size; - MPU_InitStruct.SubRegionDisable = MpuAreas[mpu_region_num].SubRegionDisable; - MPU_InitStruct.AccessPermission = MpuAreas[mpu_region_num].AccessPermission; - MPU_InitStruct.DisableExec = MpuAreas[mpu_region_num].DisableExec; - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; - MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; - MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; -#if defined(SFU_VERBOSE_DEBUG_MODE) - TRACE(" @%d:%x size:%x sub:%x perm:%x exec:%x\r\n", - MPU_InitStruct.Number, MPU_InitStruct.BaseAddress, MPU_InitStruct.Size, MPU_InitStruct.SubRegionDisable, - MPU_InitStruct.AccessPermission, MPU_InitStruct.DisableExec); -#endif /* SFU_VERBOSE_DEBUG_MODE */ - HAL_MPU_ConfigRegion(&MPU_InitStruct); - } - HAL_MPU_Enable(MPU_HARDFAULT_NMI); - e_ret_status = SFU_SUCCESS; - - - if (e_ret_status == SFU_SUCCESS) - { - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_MPU, FLOW_CTRL_MPU); - } - return e_ret_status; -} -#endif /*SFU_MPU_PROTECT_ENABLE*/ - - - -#ifdef SFU_DMA_PROTECT_ENABLE -/** - * @brief Apply DMA protection - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionDMA(void) -{ - /* - * In this function we disable the DMA buses in order to avoid that while the SB/SFU is running - * some DMA has been already enabled (e.g. through debugger in RDP-1 after reset) in order to access sensitive - * information in SRAM, FLASH - */ - /* Disable DMA1, DMA2 */ - __HAL_RCC_DMA1_CLK_DISABLE(); - - __HAL_RCC_DMA2_CLK_DISABLE(); - - __HAL_RCC_DMAMUX1_CLK_DISABLE(); - - - - - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_DMA, FLOW_CTRL_DMA); - return SFU_SUCCESS; -} -#endif /*SFU_DMA_PROTECT_ENABLE*/ - -#ifdef SFU_IWDG_PROTECT_ENABLE -/** - * @brief Apply IWDG protection - * The IWDG timeout is set to 4 second. - * Then, the IWDG reload counter is configured as below to obtain 4 second according - * to the measured LSI frequency after setting the prescaler value: - * IWDG counter clock Frequency = LSI Frequency / Prescaler value - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionIWDG(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* TIMER could be used to get the LSI frequency in order to have a more precise IWDG. - This is not used in this implementation because not necessary and in order - to optimize code-size. If you are interested, please have a look at the IWDG Cube example. */ - - /* Configure & Start the IWDG peripheral */ - /* Set counter reload value to obtain 6 sec. IWDG TimeOut. - IWDG counter clock Frequency = uwLsiFreq - Set Prescaler to 64 (IWDG_PRESCALER_64) - Timeout Period = (Reload Counter Value * 64) / uwLsiFreq - So Set Reload Counter Value = (6 * uwLsiFreq) / 64 */ - IwdgHandle.Instance = IWDG; - IwdgHandle.Init.Prescaler = IWDG_PRESCALER_64; - IwdgHandle.Init.Reload = (SFU_IWDG_TIMEOUT * LSI_VALUE / 64U); - IwdgHandle.Init.Window = IWDG_WINDOW_DISABLE; - - if (HAL_IWDG_Init(&IwdgHandle) == HAL_OK) - { - e_ret_status = SFU_SUCCESS; - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_IWDG, FLOW_CTRL_IWDG); - } - - return e_ret_status; -} -#endif /*SFU_IWDG_PROTECT_ENABLE*/ - -#ifdef SFU_DAP_PROTECT_ENABLE -/** - * @brief Set DAP protection status, configuring SWCLK and SWDIO GPIO pins. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionDAP(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - GPIO_InitTypeDef GPIO_InitStruct; - - /* Enable clock of DBG GPIO port */ - SFU_DBG_CLK_ENABLE(); - - /* Enable the DAP protections, so disable the DAP re-configuring SWCLK and SWDIO GPIO pins */ - GPIO_InitStruct.Pin = SFU_DBG_SWDIO_PIN | SFU_DBG_SWCLK_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(SFU_DBG_PORT, &GPIO_InitStruct); - e_ret_status = SFU_SUCCESS; - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_DAP, FLOW_CTRL_DAP); - - return e_ret_status; -} -#else -#endif /*SFU_DAP_PROTECT_ENABLE*/ - -#ifdef SFU_TAMPER_PROTECT_ENABLE -/** - * @brief Apply ANTI TAMPER protection - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionANTI_TAMPER(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - RTC_TamperTypeDef stamperstructure; - - /* RTC_TAMPER_1 (PC13) selected. PA0 connected to RTC_TAMPER_2 is also connected to the B1 button */ - TAMPER_GPIO_CLK_ENABLE(); - - /* Configure Tamper Pin */ - /* tamper is an additional function */ - /* not an alternate Function : config not needed */ - /* Configure the RTC peripheral */ - /* Configure RTC prescaler and RTC data registers */ - /* RTC configured as follows: - - Hour Format = Format 24 - - Asynch Prediv = Value according to source clock - - Synch Prediv = Value according to source clock - - OutPut = Output Disable - - OutPutPolarity = High Polarity - - OutPutType = Open Drain */ - RtcHandle.Instance = RTC; - RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; - RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; - RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; - RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; - RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; - RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; - - if (HAL_RTC_Init(&RtcHandle) == HAL_OK) - { - /* Configure RTC Tamper */ - stamperstructure.Tamper = RTC_TAMPER_ID; - stamperstructure.Trigger = RTC_TAMPERTRIGGER_FALLINGEDGE; - stamperstructure.Filter = RTC_TAMPERFILTER_DISABLE; - stamperstructure.SamplingFrequency = RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768; - stamperstructure.PrechargeDuration = RTC_TAMPERPRECHARGEDURATION_1RTCCLK; - stamperstructure.TamperPullUp = RTC_TAMPER_PULLUP_ENABLE; - stamperstructure.TimeStampOnTamperDetection = RTC_TIMESTAMPONTAMPERDETECTION_DISABLE; - stamperstructure.NoErase = RTC_TAMPER_ERASE_BACKUP_ENABLE; - stamperstructure.MaskFlag = RTC_TAMPERMASK_FLAG_DISABLE; - - if (HAL_RTCEx_SetTamper_IT(&RtcHandle, &stamperstructure) == HAL_OK) - { - - /* Clear the Tamper interrupt pending bit */ - __HAL_RTC_TAMPER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_TAMP_1); - e_ret_status = SFU_SUCCESS; - /* Execution stopped if flow control failed */ - FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_TAMPER, FLOW_CTRL_TAMPER); - } - } - - return e_ret_status; -} -#endif /*SFU_TAMPER_PROTECT_ENABLE*/ - -#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE -/** - * @brief Apply CLOCK MONITOR protection - * @note This function has been added just as template to be used/customized - * if a clock monitor is requested. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionCLOCK_MONITOR(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Apply the Clock Monitoring */ - /* Add your code here for customization - e.g. if HSE or LSE is used enable the CSS! - ... - ... - */ - - e_ret_status = SFU_SUCCESS; - - return e_ret_status; -} -#endif /*SFU_CLCK_MNTR_PROTECT_ENABLE*/ - -#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE -/** - * @brief Apply TEMP MONITOR protection - * @note This function has been added just as template to be used/customized - * if a temperature monitor is requested. - * @param None - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SFU_ErrorStatus SFU_LL_SECU_SetProtectionTEMP_MONITOR(void) -{ - SFU_ErrorStatus e_ret_status = SFU_ERROR; - - /* Apply the Temperature Monitoring */ - /* Add your code here for customization - ... - ... - */ - - e_ret_status = SFU_SUCCESS; - - return e_ret_status; -} -#endif /*SFU_TEMP_MNTR_PROTECT_ENABLE*/ - - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_security.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_security.h deleted file mode 100644 index 63060228..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/Target/sfu_low_level_security.h +++ /dev/null @@ -1,273 +0,0 @@ -/** - ****************************************************************************** - * @file sfu_low_level_security.h - * @author MCD Application Team - * @brief This file contains definitions for Secure Firmware Update security - * low level interface. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SFU_LOW_LEVEL_SECURITY_H -#define SFU_LOW_LEVEL_SECURITY_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Includes ------------------------------------------------------------------*/ -#include "sfu_fwimg_regions.h" -#include "sfu_def.h" - -/* Exported constants --------------------------------------------------------*/ - -/*!< Bank 1, Area A used to protect Vector Table */ -#define SFU_PROTECT_WRP_AREA_1 (OB_WRPAREA_BANK1_AREAA) - -/*!< First page including the Vector Table: 0 based */ -#define SFU_PROTECT_WRP_PAGE_START_1 ((uint32_t)((SFU_BOOT_BASE_ADDR - FLASH_BASE) / FLASH_PAGE_SIZE)) - -/*!< Last page: (code_size-1)/page_size because the page - indexes start from 0 */ -#define SFU_PROTECT_WRP_PAGE_END_1 ((uint32_t)((SFU_ROM_ADDR_END - FLASH_BASE) / FLASH_PAGE_SIZE)) - - - -/** - * @brief The regions can overlap, and can be nested. The region 7 has the highest priority - * and the region 0 has the lowest one and this governs how overlapping the regions behave. - * The priorities are fixed, and cannot be changed. - */ - - -/** - * @brief Region 0 - The Aliases Region and all User Flash & internal RAM. When executing inside SB/SFU by default all - * the Aliases and all the User Flash (used for UserApp1 and UserApp2) area must not be executable, - * but used only to read and write the downloaded code RAM is also not executable. - * From this full Area we'll enable the Execution permission only on the SB/SFU Flash Area. - */ - -#define SFU_PROTECT_MPU_AREA_USER_START ((uint32_t)0x00000000U) -#define SFU_PROTECT_MPU_AREA_USER_SIZE MPU_REGION_SIZE_1GB /*!< up to 0x3FFFFFFF */ -#define SFU_PROTECT_MPU_AREA_USER_PERM MPU_REGION_FULL_ACCESS -#define SFU_PROTECT_MPU_AREA_USER_EXEC MPU_INSTRUCTION_ACCESS_DISABLE -#define SFU_PROTECT_MPU_AREA_USER_SREG 0x00U /*!< All subregions activated */ - -/** - * @brief Region 1 and Region 2 - Enable the execution for SB/SFU Full area (SBSFU + SE + Keys). Inner region inside - * the Region 0 - */ -#define SFU_PROTECT_MPU_MAX_NB_SUBREG (8U) /*!< 8 sub-regions is the maximum */ -#define SFU_PROTECT_MPU_AREA_SFUEN_START_0 FLASH_BASE -#define SFU_PROTECT_MPU_AREA_SFUEN_START_1 0x0800C000 -#define SFU_PROTECT_MPU_AREA_SFUEN_SIZE_0 MPU_REGION_SIZE_64KB -#define SFU_PROTECT_MPU_AREA_SFUEN_SIZE_1 MPU_REGION_SIZE_4KB -#define SFU_PROTECT_MPU_AREA_SFUEN_PERM MPU_REGION_FULL_ACCESS -#define SFU_PROTECT_MPU_AREA_SFUEN_EXEC MPU_INSTRUCTION_ACCESS_ENABLE -#define SFU_PROTECT_MPU_AREA_SFUEN_SREG_0 0xC0U /*!< 64 bytes / 8 * 6 ==> 48 bytes */ -#define SFU_PROTECT_MPU_AREA_SFUEN_SREG_1 0x00U /*!< All subregions activated */ - -/** - * @brief Region 3 - Vector Table: Vector Table must be Read-Only under privileged access. Inner region inside the - * Region 1 - */ -#define SFU_PROTECT_MPU_AREA_VECT_START ((uint32_t) INTVECT_START) /*!< Vector table memory area */ -#define SFU_PROTECT_MPU_AREA_VECT_SIZE MPU_REGION_SIZE_512B -#define SFU_PROTECT_MPU_AREA_VECT_PERM MPU_REGION_PRIV_RO -#define SFU_PROTECT_MPU_AREA_VECT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE -#define SFU_PROTECT_MPU_AREA_VECT_SREG 0x00U /*!< All subregions activated */ - -/** - * @brief Region 4 - Inner region inside the Region 0 . The Option Bytes. Once the Option Bytes have been set, - * only reading will be possible - */ - -/* - * WLxx - * Single Bank - * [ 1FFF7800 1FFF7808 1FFF7810 1FFF7818 1FFF7820]: 40 bytes to be protected - * The MPU can be used to protect up to eight memory regions. - * These, in turn can have eight subregions, if the region is at least 256 bytes. - * Here, we define a 64B region so subregions cannot be used. - */ -#define SFU_PROTECT_MPU_AREA_OB_BANK1_START ((uint32_t)0x1FFF7800U) /*!< Option Bytes in bank 1 */ -#define SFU_PROTECT_MPU_AREA_OB_BANK1_SIZE MPU_REGION_SIZE_64B /*!< Protecting more than required */ -#define SFU_PROTECT_MPU_AREA_OB_BANK1_PERM MPU_REGION_NO_ACCESS -#define SFU_PROTECT_MPU_AREA_OB_BANK1_EXEC MPU_INSTRUCTION_ACCESS_DISABLE -#define SFU_PROTECT_MPU_AREA_OB_BANK1_SREG 0x00U /*!< Subregion mask to deactivate unexpected - MPU subregions: 0x1F should be set but it - would have no effect as we have a 64B - region */ - -/** - * @brief Region 5 - Peripherals Area - */ -#define SFU_PROTECT_MPU_AREA_PERIPH_START PERIPH_BASE /*!< Peripheral memory area */ -#define SFU_PROTECT_MPU_AREA_PERIPH_SIZE MPU_REGION_SIZE_512MB /*!< To be coherent with the peripherals - memory area */ -#define SFU_PROTECT_MPU_AREA_PERIPH_PERM MPU_REGION_FULL_ACCESS -#define SFU_PROTECT_MPU_AREA_PERIPH_EXEC MPU_INSTRUCTION_ACCESS_DISABLE -#define SFU_PROTECT_MPU_AREA_PERIPH_SREG 0x00U /*!< All subregions activated */ - - -/** - * MPU configuration for UserApp execution - * ======================================= - * @brief Region 6 & 7 - Enable the execution of the active slots - * MPU constraint = Region base address should be aligned on Region size - */ -/** - * Region definition : from 0x0800 F800 ==> 0x0800 FFFF (2 kbytes) - */ -#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_START SLOT_ACTIVE_1_START -#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SIZE MPU_REGION_SIZE_2KB -#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_PERM MPU_REGION_FULL_ACCESS -#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE -#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SREG 0x00U /*!< All subregions activated */ -/** - * Additional Region definition : from 0x0801 0000 ==> 0x0803 FFFF (192 kbytes) - */ -#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_START FLASH_BASE -#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SIZE MPU_REGION_SIZE_256KB -#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_PERM MPU_REGION_FULL_ACCESS -#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE -#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SREG 0x03U /*!< 256 Kbytes / 8 * 6 ==> 192 Kbytes */ - - -/** - * @} - */ - -/** @defgroup SFU_CONFIG_TAMPER Tamper Configuration - * @{ - */ -#define TAMPER_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define RTC_TAMPER_ID RTC_TAMPER_1 -#define RTC_TAMPER_ID_INTERRUPT RTC_IT_TAMP_1 - -/** - * @} - */ - -/** @defgroup SFU_CONFIG_DBG Debug Port Configuration - * @{ - */ -#define SFU_DBG_PORT GPIOA -#define SFU_DBG_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() -#define SFU_DBG_SWDIO_PIN GPIO_PIN_13 -#define SFU_DBG_SWCLK_PIN GPIO_PIN_14 - - -/** - * @} - */ - -/** - * @} - */ - -/** @defgroup SFU_SECURITY_Exported_Constants Exported Constants - * @{ - */ - -/** @defgroup SFU_SECURITY_Exported_Constants_Wakeup FU WAKEUP ID Type definition - * @{ - */ -typedef enum -{ - SFU_RESET_UNKNOWN = 0x00U, - SFU_RESET_WDG_RESET, - SFU_RESET_LOW_POWER, - SFU_RESET_HW_RESET, - SFU_RESET_BOR_RESET, - SFU_RESET_SW_RESET, - SFU_RESET_OB_LOADER, -} SFU_RESET_IdTypeDef; - -/** - * @} - */ - -/** @defgroup SFU_SECURITY_Exported_Constants_Protections FU SECURITY Protections_Constants - * @{ - */ -#define SFU_PROTECTIONS_NONE ((uint32_t)0x00000000U) /*!< Protection configuration unchanged */ -#define SFU_STATIC_PROTECTION_RDP ((uint32_t)0x00000001U) /*!< RDP protection level 1 is applied */ -#define SFU_STATIC_PROTECTION_WRP ((uint32_t)0x00000002U) /*!< Constants section in Flash. Needed as - separate section to support PCRoP */ -#define SFU_STATIC_PROTECTION_PCROP ((uint32_t)0x00000004U) /*!< SFU App section in Flash */ -#define SFU_STATIC_PROTECTION_LOCKED ((uint32_t)0x00000008U) /*!< RDP Level2 is applied. The device is Locked! - Std Protections cannot be - added/removed/modified */ -#define SFU_STATIC_PROTECTION_BFB2 ((uint32_t)0x00000010U) /*!< BFB2 is disabled. The device shall always - boot in bank1! */ - -#define SFU_RUNTIME_PROTECTION_MPU ((uint32_t)0x00000100U) /*!< Shared Info section in Flash */ -#define SFU_RUNTIME_PROTECTION_IWDG ((uint32_t)0x00000400U) /*!< Independent Watchdog */ -#define SFU_RUNTIME_PROTECTION_DAP ((uint32_t)0x00000800U) /*!< Debug Access Port control */ -#define SFU_RUNTIME_PROTECTION_DMA ((uint32_t)0x00001000U) /*!< DMA protection, disable DMAs */ -#define SFU_RUNTIME_PROTECTION_ANTI_TAMPER ((uint32_t)0x00002000U) /*!< Anti-Tampering protections */ -#define SFU_RUNTIME_PROTECTION_CLOCK_MONITOR ((uint32_t)0x00004000U) /*!< Activate a clock monitoring */ -#define SFU_RUNTIME_PROTECTION_TEMP_MONITOR ((uint32_t)0x00008000U) /*!< Activate a Temperature monitoring */ - -#define SFU_STATIC_PROTECTION_ALL (SFU_STATIC_PROTECTION_RDP | SFU_STATIC_PROTECTION_WRP | \ - SFU_STATIC_PROTECTION_PCROP | SFU_STATIC_PROTECTION_LOCKED) -/*!< All the static protections */ - -#define SFU_RUNTIME_PROTECTION_ALL (SFU_RUNTIME_PROTECTION_MPU | SFU_RUNTIME_PROTECTION_FWALL | \ - SFU_RUNTIME_PROTECTION_IWDG | SFU_RUNTIME_PROTECTION_DAP | \ - SFU_RUNTIME_PROTECTION_DMA | SFU_RUNTIME_PROTECTION_ANTI_TAMPER | \ - SFU_RUNTIME_PROTECTION_CLOCK_MONITOR | SFU_RUNTIME_PROTECTION_TEMP_MONITOR) -/*!< All the run-time protections */ - -#define SFU_INITIAL_CONFIGURATION (0x00U) /*!< Initial configuration */ -#define SFU_SECOND_CONFIGURATION (0x01U) /*!< Second configuration */ -#define SFU_THIRD_CONFIGURATION (0x02U) /*!< Third configuration */ - -/* Exported functions ------------------------------------------------------- */ -#define SFU_CALLBACK_ANTITAMPER HAL_RTCEx_Tamper1EventCallback -/*!
      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.
      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef APP_HW_H -#define APP_HW_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Exported macros -----------------------------------------------------------*/ -#define BUTTON_INIT() BSP_PB_Init(BUTTON_SW1,BUTTON_MODE_GPIO); -#define BUTTON_PUSHED() ((uint32_t) BSP_PB_GetState(BUTTON_SW1) == (uint32_t)GPIO_PIN_RESET) - - -#ifdef __cplusplus -} -#endif - -#endif /* APP_HW_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h deleted file mode 100644 index 6b8db4f7..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - ****************************************************************************** - * @file stm32wlxx_nucleo_conf.h - * @author MCD Application Team - * @brief STM32WLxx_Nucleo board configuration file. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32WLXX_NUCLEO_CONF_H -#define STM32WLXX_NUCLEO_CONF_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32wlxx_hal.h" - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup STM32WLXX_NUCLEO - * @{ - */ - -/** @defgroup STM32WLXX_NUCLEO_CONFIG CONFIG - * @{ - */ - -/** @defgroup STM32WLXX_NUCLEO_CONFIG_Exported_Constants Exported Constants - * @{ - */ -/* COM usage define */ -#define USE_BSP_COM_FEATURE 0U - -/* COM log define */ -#define USE_COM_LOG 0U - -/* IRQ priorities */ -#define BSP_BUTTON_SWx_IT_PRIORITY 15U - -/* Radio maximum wakeup time (in ms) */ -#define RF_WAKEUP_TIME 100U - -/* Indicates whether or not TCXO is supported by the board - * 0: TCXO not supported - * 1: TCXO supported - */ -#define IS_TCXO_SUPPORTED 0U - -/* Indicates whether or not DCDC is supported by the board - * 0: DCDC not supported - * 1: DCDC supported - */ -#define IS_DCDC_SUPPORTED 1U - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32WLXX_NUCLEO_CONF_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/main.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/main.c deleted file mode 100644 index 771eb7dd..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/main.c +++ /dev/null @@ -1,157 +0,0 @@ -/** - ****************************************************************************** - * @file main.c - * @author MCD Application Team - * @brief Main application file. - * This application demonstrates Secure Boot and Secure Firmware Update. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "sfu_boot.h" - - -/* Private variables ---------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -void SystemClock_Config(void); - -/* Functions Definition ------------------------------------------------------*/ -/** - * @brief main function - * @param None - * @retval int - */ -int main(void) -{ - - /* MCU Configuration--------------------------------------------------------*/ - /* Configure the system clock using LL functions */ - SystemClock_Config(); - - /* This part is NOT secure (security mechanisms NOT enabled yet) */ - /* Reset of all peripherals, Initializes the Flash interface and the Systick*/ - (void) HAL_Init(); - - /* Board BSP Configuration-------------------------------------------------*/ - /* - * As the secure mode has not been entered yet, we do not configure BSP right now . - * The BSP will be configured by the bootloader. - */ - - - /* Launch the Bootloader----------------------------------------------------*/ - /* - * This is the beginning of the secure part: - * security mechanisms will be enabled. - * The function below should not return (unless a critical failure is encountered). - */ - (void)SFU_BOOT_RunSecureBootService(); /* no need to take care of the returned value as we reboot in all cases */ - - /* Security or SecureBoot initialization failure. Force a System Reset */ - SFU_BOOT_ForceReboot(); - -} - -/** - * @brief System Clock Configuration - * The system Clock is configured as follows : - * System Clock source = PLL (MSI) - * SYSCLK(Hz) = 48000000 - * HCLK(Hz) = 48000000 - * AHB1 Prescaler = 1 - * AHB3 Prescaler = 1 - * APB1 Prescaler = 1 - * APB2 Prescaler = 1 - * MSI Frequency(Hz) = 4000000 - * PLL_M = 1 - * PLL_N = 24 - * PLL_R = 2 - * Flash Latency(WS) = 2 - * Voltage range = 1 - * @param None - * @retval None - */ -void SystemClock_Config(void) -{ - LL_FLASH_SetLatency(LL_FLASH_LATENCY_2); - - while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) - { - }; - - LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); - LL_RCC_MSI_Enable(); - - /* Wait till MSI is ready */ - while(LL_RCC_MSI_IsReady() != 1) - { - }; - - LL_RCC_MSI_EnableRangeSelection(); - LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6); - LL_RCC_MSI_SetCalibTrimming(0); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 24, LL_RCC_PLLR_DIV_2); - LL_RCC_PLL_EnableDomain_SYS(); - LL_RCC_PLL_Enable(); - - /* Wait till PLL is ready */ - while(LL_RCC_PLL_IsReady() != 1) - { - }; - - LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); - - /* Wait till System clock is ready */ - while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) - { - }; - - LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); - LL_RCC_SetAHB3Prescaler(LL_RCC_SYSCLK_DIV_1); - LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); - LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - - LL_Init1msTick(48000000); - - /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */ - LL_SetSystemCoreClock(48000000); -} - - - - - -#ifdef USE_FULL_ASSERT - -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t *file, uint32_t line) -{ - /* USER CODE BEGIN 6 */ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ - /* USER CODE END 6 */ - -} - -#endif /* USE_FULL_ASSERT */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/stm32wlxx_it.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/stm32wlxx_it.c deleted file mode 100644 index 818ce0d5..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/stm32wlxx_it.c +++ /dev/null @@ -1,121 +0,0 @@ -/** - ****************************************************************************** - * @file stm32wlxx_it.c - * @author MCD Application Team - * @brief Interrupt Service Routines. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "stm32wlxx_it.h" - -/* Global variables ----------------------------------------------------------*/ -/* RTC handler declaration */ -RTC_HandleTypeDef RtcHandle; - -/* Functions Definition ------------------------------------------------------*/ -/******************************************************************************/ -/* Cortex-M4 Processor Interruption and Exception Handlers */ -/******************************************************************************/ - -/* Exception handlers are implemented in the various source files of sbsfu application */ - -/* NMI exception handler is implemented in sfu_low_level_flash_int.c file */ -/* Hard Fault exception handler is implemented in sfu_boot.c file */ -/* Memory Manage exception handler is implemented in sfu_boot.c file */ -/** - * @brief This function handles Bus Fault exception. - * @param None - * @retval None - */ -void BusFault_Handler(void) -{ - /* Go to infinite loop when Bus Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Usage Fault exception. - * @param None - * @retval None - */ -void UsageFault_Handler(void) -{ - /* Go to infinite loop when Usage Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles SVCall exception. - * @param None - * @retval None - */ -void SVC_Handler(void) -{ -} - -/** - * @brief This function handles Debug Monitor exception. - * @param None - * @retval None - */ -void DebugMon_Handler(void) -{ -} - -/** - * @brief This function handles PendSVC exception. - * @param None - * @retval None - */ -void PendSV_Handler(void) -{ -} - -/** - * @brief This function handles SysTick Handler. - * @param None - * @retval None - */ -void SysTick_Handler(void) -{ - HAL_IncTick(); -} - -/******************************************************************************/ -/* STM32WLxx Peripherals Interrupt Handlers */ -/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ -/* available peripheral interrupt handler's name please refer to the startup */ -/* file (startup_stm32wlxx.s). */ -/******************************************************************************/ -#ifdef SFU_TAMPER_PROTECT_ENABLE -/** - * @brief This function handles Tamper interrupt request. - * @param None - * @retval None - */ -void TAMP_STAMP_LSECSS_SSRU_IRQHandler() -{ - HAL_RTCEx_TamperIRQHandler(&RtcHandle); -} -#endif /* SFU_TAMPER_PROTECT_ENABLE */ - - - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/Project.ewp deleted file mode 100644 index 24b33bbd..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/Project.ewp +++ /dev/null @@ -1,1230 +0,0 @@ - - - 2 - - STM32WL55JC_Nucleo_1_Image_BFU - - ARM - - 1 - - General - 3 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 34 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 10 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - $TOOLKIT_DIR$\bin\isymexport.exe --edit "$PROJ_DIR$\steering_file.txt" "$TARGET_PATH$" "$PROJ_DIR$.\se_interface_appli.o" - - - - ILINK - 0 - - 21 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - - Doc - - $PROJ_DIR$\..\readme.txt - - - - Application - - Core - - $PROJ_DIR$\..\Core\Src\main.c - - - $PROJ_DIR$\..\Core\Src\stm32wlxx_hal_msp.c - - - $PROJ_DIR$\..\Core\Src\stm32wlxx_it.c - - - - BFU - - App - - $PROJ_DIR$\..\BFU\App\sfu_loader.c - - - $PROJ_DIR$\..\BFU\App\sfu_boot.c - - - $PROJ_DIR$\..\BFU\App\sfu_com_loader.c - - - $PROJ_DIR$\..\BFU\App\sfu_com_trace.c - - - $PROJ_DIR$\..\BFU\App\sfu_error.c - - - $PROJ_DIR$\..\BFU\App\sfu_test.c - - - $PROJ_DIR$\..\BFU\App\sfu_fwimg_common.c - - - $PROJ_DIR$\..\BFU\App\sfu_new_image.c - - - $PROJ_DIR$\..\BFU\App\sfu_kms.c - - - $PROJ_DIR$\..\BFU\App\sfu_interface_crypto_scheme.c - - - - Target - - $PROJ_DIR$\..\BFU\Target\sfu_low_level.c - - - $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash.c - - - $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash_int.c - - - $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash_ext.c - - - $PROJ_DIR$\..\BFU\Target\sfu_low_level_security.c - - - - - EWARM - - $PROJ_DIR$\startup_stm32wl55xx_cm4.s - - - - - Drivers - - BSP - - STM32WLxx_Nucleo - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\BSP\STM32WLxx_Nucleo\stm32wlxx_nucleo.c - - - - - STM32WLxx_HAL_Driver - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cortex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_gpio.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_iwdg.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_exti.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c - - - - STM32WLxx_LL_Driver - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_ll_utils.c - - - - CMSIS - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\CMSIS\Device\ST\STM32WLxx\Source\Templates\system_stm32wlxx.c - - - - - Middlewares - - STM32_Secure_Engine - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_application.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_bootloader.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_common.c - - - - STM32_Key_Management_Services - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\iKMS\se_interface_kms.c - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s deleted file mode 100644 index 1431e7f3..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s +++ /dev/null @@ -1,509 +0,0 @@ -;******************************************************************************** -;* File Name : startup_stm32wl55xx_cm4.s -;* Author : MCD Application Team -;* Description : M4 core vector table of the STM32WLxxxx devices for the -;* IAR (EWARM) toolchain. -;* -;* This module performs: -;* - Set the initial SP -;* - Set the initial PC == _iar_program_start, -;* - Set the vector table entries with the exceptions ISR -;* address. -;* - Branches to main in the C library (which eventually -;* calls main()). -;* After Reset the Cortex-M4 processor is in Thread mode, -;* priority is Privileged, and the Stack is set to Main. -;******************************************************************************** -;* -;* Copyright (c) 2020 STMicroelectronics. All rights reserved. -;* -;* This software component is licensed by ST under 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: -;* opensource.org/licenses/Apache-2.0 -; -;******************************************************************************* -; -; -; The modules in this file are included in the libraries, and may be replaced -; by any user-defined modules that define the PUBLIC symbol _program_start or -; a user defined start symbol. -; To override the cstartup defined in the library, simply add your modified -; version to the workbench project. -; -; The vector table is normally located at address 0. -; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. -; The name "__vector_table" has special meaning for C-SPY: -; it is where the SP start value is found, and the NVIC vector -; table register (VTOR) is initialized to this address if != 0. -; -; Cortex-M version -; - - MODULE ?cstartup - - ;; Forward declaration of sections. - SECTION CSTACK:DATA:NOROOT(3) - - SECTION .intvec:CODE:NOROOT(2) - - EXTERN __iar_program_start - EXTERN SystemInit - PUBLIC __vector_table - - DATA -__vector_table - DCD sfe(CSTACK) - DCD Reset_Handler ; Reset Handler - - DCD NMI_Handler ; NMI Handler - DCD HardFault_Handler ; Hard Fault Handler - DCD MemManage_Handler ; MPU Fault Handler - DCD BusFault_Handler ; Bus Fault Handler - DCD UsageFault_Handler ; Usage Fault Handler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD SVC_Handler ; SVCall Handler - DCD DebugMon_Handler ; Debug Monitor Handler - DCD 0 ; Reserved - DCD PendSV_Handler ; PendSV Handler - DCD SysTick_Handler ; SysTick Handler - - ; External Interrupts - DCD WWDG_IRQHandler ; Window WatchDog - DCD PVD_PVM_IRQHandler ; PVD and PVM Interrupt - DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSRU Interrupts - DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt - DCD FLASH_IRQHandler ; FLASH global Interrupt - DCD RCC_IRQHandler ; RCC Interrupt - DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt - DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt - DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt - DCD EXTI3_IRQHandler ; EXTI Line 3 Interrupt - DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt - DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt - DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt - DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt - DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt - DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt - DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt - DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt - DCD ADC_IRQHandler ; ADC Interrupt - DCD DAC_IRQHandler ; DAC Interrupt - DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV Interrupt - DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts - DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt - DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt - DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt - DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts - DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt - DCD TIM2_IRQHandler ; TIM2 Global Interrupt - DCD TIM16_IRQHandler ; TIM16 Global Interrupt - DCD TIM17_IRQHandler ; TIM17 Global Interrupt - DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt - DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt - DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt - DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt - DCD SPI1_IRQHandler ; SPI1 Interrupt - DCD SPI2_IRQHandler ; SPI2 Interrupt - DCD USART1_IRQHandler ; USART1 Interrupt - DCD USART2_IRQHandler ; USART2 Interrupt - DCD LPUART1_IRQHandler ; LPUART1 Interrupt - DCD LPTIM1_IRQHandler ; LPTIM1 Global Interrupt - DCD LPTIM2_IRQHandler ; LPTIM2 Global Interrupt - DCD EXTI15_10_IRQHandler ; EXTI Lines [15:10] Interrupt - DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt - DCD LPTIM3_IRQHandler ; LPTIM3 Global Interrupt - DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt - DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt - DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt - DCD HSEM_IRQHandler ; HSEM0 Interrupt - DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt - DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt - DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt - DCD AES_IRQHandler ; AES Interrupt - DCD RNG_IRQHandler ; RNG1 Interrupt - DCD PKA_IRQHandler ; PKA Interrupt - DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt - DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt - DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt - DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt - DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt - DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt - DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt - DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Default interrupt handlers. -;; - THUMB - - PUBWEAK Reset_Handler - SECTION .text:CODE:NOROOT:REORDER(2) -Reset_Handler - LDR R0, =SystemInit - BLX R0 - LDR R0, =__iar_program_start - BX R0 - - PUBWEAK NMI_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -NMI_Handler - B NMI_Handler - - PUBWEAK HardFault_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -HardFault_Handler - B HardFault_Handler - - PUBWEAK MemManage_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -MemManage_Handler - B MemManage_Handler - - PUBWEAK BusFault_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -BusFault_Handler - B BusFault_Handler - - PUBWEAK UsageFault_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -UsageFault_Handler - B UsageFault_Handler - - PUBWEAK SVC_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -SVC_Handler - B SVC_Handler - - PUBWEAK DebugMon_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -DebugMon_Handler - B DebugMon_Handler - - PUBWEAK PendSV_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -PendSV_Handler - B PendSV_Handler - - PUBWEAK SysTick_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -SysTick_Handler - B SysTick_Handler - - PUBWEAK WWDG_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -WWDG_IRQHandler - B WWDG_IRQHandler - - PUBWEAK PVD_PVM_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -PVD_PVM_IRQHandler - B PVD_PVM_IRQHandler - - PUBWEAK TAMP_STAMP_LSECSS_SSRU_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TAMP_STAMP_LSECSS_SSRU_IRQHandler - B TAMP_STAMP_LSECSS_SSRU_IRQHandler - - PUBWEAK RTC_WKUP_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RTC_WKUP_IRQHandler - B RTC_WKUP_IRQHandler - - PUBWEAK FLASH_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -FLASH_IRQHandler - B FLASH_IRQHandler - - PUBWEAK RCC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RCC_IRQHandler - B RCC_IRQHandler - - PUBWEAK EXTI0_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI0_IRQHandler - B EXTI0_IRQHandler - - PUBWEAK EXTI1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI1_IRQHandler - B EXTI1_IRQHandler - - PUBWEAK EXTI2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI2_IRQHandler - B EXTI2_IRQHandler - - PUBWEAK EXTI3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI3_IRQHandler - B EXTI3_IRQHandler - - PUBWEAK EXTI4_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI4_IRQHandler - B EXTI4_IRQHandler - - PUBWEAK DMA1_Channel1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel1_IRQHandler - B DMA1_Channel1_IRQHandler - - PUBWEAK DMA1_Channel2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel2_IRQHandler - B DMA1_Channel2_IRQHandler - - PUBWEAK DMA1_Channel3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel3_IRQHandler - B DMA1_Channel3_IRQHandler - - PUBWEAK DMA1_Channel4_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel4_IRQHandler - B DMA1_Channel4_IRQHandler - - PUBWEAK DMA1_Channel5_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel5_IRQHandler - B DMA1_Channel5_IRQHandler - - PUBWEAK DMA1_Channel6_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel6_IRQHandler - B DMA1_Channel6_IRQHandler - - PUBWEAK DMA1_Channel7_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel7_IRQHandler - B DMA1_Channel7_IRQHandler - - PUBWEAK ADC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -ADC_IRQHandler - B ADC_IRQHandler - - PUBWEAK DAC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DAC_IRQHandler - B DAC_IRQHandler - - PUBWEAK C2SEV_PWR_C2H_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -C2SEV_PWR_C2H_IRQHandler - B C2SEV_PWR_C2H_IRQHandler - - PUBWEAK COMP_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -COMP_IRQHandler - B COMP_IRQHandler - - PUBWEAK EXTI9_5_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI9_5_IRQHandler - B EXTI9_5_IRQHandler - - PUBWEAK TIM1_BRK_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_BRK_IRQHandler - B TIM1_BRK_IRQHandler - - PUBWEAK TIM1_UP_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_UP_IRQHandler - B TIM1_UP_IRQHandler - - PUBWEAK TIM1_TRG_COM_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_TRG_COM_IRQHandler - B TIM1_TRG_COM_IRQHandler - - PUBWEAK TIM1_CC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_CC_IRQHandler - B TIM1_CC_IRQHandler - - PUBWEAK TIM2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM2_IRQHandler - B TIM2_IRQHandler - - PUBWEAK TIM16_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM16_IRQHandler - B TIM16_IRQHandler - - PUBWEAK TIM17_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM17_IRQHandler - B TIM17_IRQHandler - - PUBWEAK I2C1_EV_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C1_EV_IRQHandler - B I2C1_EV_IRQHandler - - PUBWEAK I2C1_ER_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C1_ER_IRQHandler - B I2C1_ER_IRQHandler - - PUBWEAK I2C2_EV_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C2_EV_IRQHandler - B I2C2_EV_IRQHandler - - PUBWEAK I2C2_ER_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C2_ER_IRQHandler - B I2C2_ER_IRQHandler - - PUBWEAK SPI1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SPI1_IRQHandler - B SPI1_IRQHandler - - PUBWEAK SPI2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SPI2_IRQHandler - B SPI2_IRQHandler - - PUBWEAK USART1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -USART1_IRQHandler - B USART1_IRQHandler - - PUBWEAK USART2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -USART2_IRQHandler - B USART2_IRQHandler - - PUBWEAK LPUART1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPUART1_IRQHandler - B LPUART1_IRQHandler - - PUBWEAK LPTIM1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPTIM1_IRQHandler - B LPTIM1_IRQHandler - - PUBWEAK LPTIM2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPTIM2_IRQHandler - B LPTIM2_IRQHandler - - PUBWEAK EXTI15_10_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI15_10_IRQHandler - B EXTI15_10_IRQHandler - - PUBWEAK RTC_Alarm_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RTC_Alarm_IRQHandler - B RTC_Alarm_IRQHandler - - PUBWEAK LPTIM3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPTIM3_IRQHandler - B LPTIM3_IRQHandler - - PUBWEAK SUBGHZSPI_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SUBGHZSPI_IRQHandler - B SUBGHZSPI_IRQHandler - - PUBWEAK IPCC_C1_RX_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -IPCC_C1_RX_IRQHandler - B IPCC_C1_RX_IRQHandler - - PUBWEAK IPCC_C1_TX_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -IPCC_C1_TX_IRQHandler - B IPCC_C1_TX_IRQHandler - - PUBWEAK HSEM_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -HSEM_IRQHandler - B HSEM_IRQHandler - - PUBWEAK I2C3_EV_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C3_EV_IRQHandler - B I2C3_EV_IRQHandler - - PUBWEAK I2C3_ER_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C3_ER_IRQHandler - B I2C3_ER_IRQHandler - - PUBWEAK SUBGHZ_Radio_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SUBGHZ_Radio_IRQHandler - B SUBGHZ_Radio_IRQHandler - - PUBWEAK AES_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -AES_IRQHandler - B AES_IRQHandler - - PUBWEAK RNG_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RNG_IRQHandler - B RNG_IRQHandler - - PUBWEAK PKA_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -PKA_IRQHandler - B PKA_IRQHandler - - PUBWEAK DMA2_Channel1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel1_IRQHandler - B DMA2_Channel1_IRQHandler - - PUBWEAK DMA2_Channel2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel2_IRQHandler - B DMA2_Channel2_IRQHandler - - PUBWEAK DMA2_Channel3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel3_IRQHandler - B DMA2_Channel3_IRQHandler - - PUBWEAK DMA2_Channel4_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel4_IRQHandler - B DMA2_Channel4_IRQHandler - - PUBWEAK DMA2_Channel5_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel5_IRQHandler - B DMA2_Channel5_IRQHandler - - PUBWEAK DMA2_Channel6_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel6_IRQHandler - B DMA2_Channel6_IRQHandler - - PUBWEAK DMA2_Channel7_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel7_IRQHandler - B DMA2_Channel7_IRQHandler - - PUBWEAK DMAMUX1_OVR_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMAMUX1_OVR_IRQHandler - B DMAMUX1_OVR_IRQHandler - - END - -;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/steering_file.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/steering_file.txt deleted file mode 100644 index 15a2041f..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/steering_file.txt +++ /dev/null @@ -1,38 +0,0 @@ -show SE_APP_GetActiveFwInfo -show SE_APP_ValidateFw -show SE_KMS_Initialize -show SE_KMS_Finalize -show SE_KMS_GetInfo -show SE_KMS_GetFunctionList -show SE_KMS_GetSlotList -show SE_KMS_GetSlotInfo -show SE_KMS_GetTokenInfo -show SE_KMS_GetMechanismInfo -show SE_KMS_OpenSession -show SE_KMS_CloseSession -show SE_KMS_CreateObject -show SE_KMS_DestroyObject -show SE_KMS_GetAttributeValue -show SE_KMS_SetAttributeValue -show SE_KMS_FindObjectsInit -show SE_KMS_FindObjects -show SE_KMS_FindObjectsFinal -show SE_KMS_EncryptInit -show SE_KMS_Encrypt -show SE_KMS_EncryptUpdate -show SE_KMS_EncryptFinal -show SE_KMS_DecryptInit -show SE_KMS_Decrypt -show SE_KMS_DecryptUpdate -show SE_KMS_DecryptFinal -show SE_KMS_DigestInit -show SE_KMS_Digest -show SE_KMS_DigestUpdate -show SE_KMS_DigestFinal -show SE_KMS_SignInit -show SE_KMS_Sign -show SE_KMS_VerifyInit -show SE_KMS_Verify -show SE_KMS_DeriveKey -show SE_KMS_GenerateKeyPair -show SE_KMS_GenerateRandom diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/Project.uvprojx deleted file mode 100644 index 42bdad70..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/Project.uvprojx +++ /dev/null @@ -1,698 +0,0 @@ - - - - 2.1 - -
      ### uVision Project, (C) Keil Software
      - - - - STM32WL55JC_Nucleo_1_Image_BFU - 0x4 - ARM-ADS - 6120000::V6.12::.\ARMCLANG - 1 - - - STM32WL55JCIx:CM4 - STMicroelectronics - Keil.STM32WLxx_DFP.1.0.4 - http://www.keil.com/pack - IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) - 0 - $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h - - - - - - - - - - $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\STM32WL55JC_Nucleo\Exe\ - BFU - 1 - 0 - 0 - 1 - 1 - - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 1 - 0 - fromelf #L --bincombined --output=$L@L.bin - - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 0 - - - SARMCM3.DLL - -REMAP -MPU - DCM.DLL - -pCM4 - SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4096 - - 1 - BIN\UL2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M4" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 1 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 1 - 0x8000000 - 0x40000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x8000000 - 0x40000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 0 - 0x0 - 0x0 - - - - - - 1 - 7 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 0 - 1 - 0 - 0 - 5 - 3 - 0 - 0 - 0 - 0 - 0 - - -Wno-format - USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED - - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../Core/Inc;../BFU/App;../BFU/Target;../../1_Image_SECoreBin/Inc;../../Linker_Common/MDK-ARM;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../../../../../Middlewares/ST/STM32_Secure_Engine/Interface;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS;../../../../../../Drivers/BSP/STM32WLxx_Nucleo - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - - - - BFU.sct - - - --symdefs=se_interface_appli.txt ---keep=SE_CORE_Bin.o(SE_CORE_Bin) - - - - - - - - Application/Core - - - main.c - 1 - ../Core/Src/main.c - - - stm32wlxx_hal_msp.c - 1 - ../Core/Src/stm32wlxx_hal_msp.c - - - stm32wlxx_it.c - 1 - ../Core/Src/stm32wlxx_it.c - - - - - Application/MDK-ARM - - - se_core_bin.s - 2 - se_core_bin.s - - - startup_stm32wl55xx_cm4.s - 2 - startup_stm32wl55xx_cm4.s - - - - - Application/BFU/App - - - sfu_boot.c - 1 - ../BFU/App/sfu_boot.c - - - sfu_com_loader.c - 1 - ..\BFU\App\sfu_com_loader.c - - - sfu_com_trace.c - 1 - ..\BFU\App\sfu_com_trace.c - - - sfu_error.c - 1 - ../BFU/App/sfu_error.c - - - sfu_fwimg_common.c - 1 - ../BFU/App/sfu_fwimg_common.c - - - sfu_interface_crypto_scheme.c - 1 - ../BFU/App/sfu_interface_crypto_scheme.c - - - sfu_kms.c - 1 - ../BFU/App/sfu_kms.c - - - sfu_loader.c - 1 - ..\BFU\App\sfu_loader.c - - - sfu_new_image.c - 1 - ..\BFU\App\sfu_new_image.c - - - sfu_test.c - 1 - ../BFU/App/sfu_test.c - - - - - Application/BFU/Target - - - sfu_low_level.c - 1 - ..\BFU\Target\sfu_low_level.c - - - sfu_low_level_flash.c - 1 - ..\BFU\Target\sfu_low_level_flash.c - - - sfu_low_level_flash_ext.c - 1 - ..\BFU\Target\sfu_low_level_flash_ext.c - - - sfu_low_level_flash_int.c - 1 - ..\BFU\Target\sfu_low_level_flash_int.c - - - sfu_low_level_security.c - 1 - ../BFU/Target/sfu_low_level_security.c - - - - - Doc - - - readme.txt - 5 - ../readme.txt - - - - - Drivers/BSP/STM32WLxx_Nucleo - - - stm32wlxx_nucleo.c - 1 - ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c - - - - - Drivers/STM32WLxx_HAL_Driver - - - stm32wlxx_hal.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c - - - stm32wlxx_hal_cortex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c - - - stm32wlxx_hal_crc.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - - - stm32wlxx_hal_crc_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - - - stm32wlxx_hal_dma.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c - - - stm32wlxx_hal_flash.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - - - stm32wlxx_hal_flash_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - - - stm32wlxx_hal_gpio.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c - - - stm32wlxx_hal_iwdg.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c - - - stm32wlxx_hal_pwr.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c - - - stm32wlxx_hal_pwr_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c - - - stm32wlxx_hal_rcc.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c - - - stm32wlxx_hal_rcc_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c - - - stm32wlxx_hal_rtc.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c - - - stm32wlxx_hal_rtc_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c - - - stm32wlxx_hal_spi.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi.c - - - stm32wlxx_hal_spi_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi_ex.c - - - stm32wlxx_hal_tim.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim.c - - - stm32wlxx_hal_tim_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim_ex.c - - - stm32wlxx_hal_uart.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c - - - stm32wlxx_hal_uart_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c - - - stm32wlxx_hal_exti.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c - - - - - Drivers/CMSIS - - - system_stm32wlxx.c - 1 - ../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Source/Templates/system_stm32wlxx.c - - - - - Middlewares/STM32_Secure_Engine - - - se_interface_application.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_application.c - - - se_interface_bootloader.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_bootloader.c - - - se_interface_common.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_common.c - - - - - Middlewares/STM32_Key_Management_Services - - - se_interface_kms.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS/se_interface_kms.c - - - - - Drivers/STM32WLxx_LL_Driver - - - stm32wlxx_ll_utils.c - 1 - ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_ll_utils.c - - - - - - - - - - - - - -
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/.cproject deleted file mode 100644 index c1590b94..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/.cproject +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/.project deleted file mode 100644 index c70b9549..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/.project +++ /dev/null @@ -1,271 +0,0 @@ - - - 1_Image_BFU - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - com.st.stm32cube.ide.mcu.MCUProjectNature - org.eclipse.cdt.core.cnature - com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature - com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature - com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature - com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature - com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature - com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature - com.st.stm32cube.ide.mcu.MCURootProjectNature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - - - Doc/readme.txt - 1 - $%7BPARENT-2-PROJECT_LOC%7D/readme.txt - - - Application/Core/main.c - 1 - PARENT-1-PROJECT_LOC/Core/Src/main.c - - - Application/Core/stm32wlxx_hal_msp.c - 1 - PARENT-1-PROJECT_LOC/Core/Src/stm32wlxx_hal_msp.c - - - Application/Core/stm32wlxx_it.c - 1 - PARENT-1-PROJECT_LOC/Core/Src/stm32wlxx_it.c - - - Drivers/CMSIS/system_stm32wlxx.c - 1 - PARENT-6-PROJECT_LOC/Drivers/CMSIS/Device/ST/STM32WLxx/Source/Templates/system_stm32wlxx.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cortex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_exti.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gpio.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_iwdg.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_spi.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_spi_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_tim.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_tim_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c - - - Drivers/STM32WLxx_LL_Driver/stm32wlxx_ll_utils.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_ll_utils.c - - - Middlewares/STM32_Key_Management_Services/se_interface_kms.c - 1 - PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Key_Management_Services/iKMS/se_interface_kms.c - - - Middlewares/STM32_Secure_Engine/se_interface_application.c - 1 - PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_application.c - - - Middlewares/STM32_Secure_Engine/se_interface_bootloader.c - 1 - PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_bootloader.c - - - Middlewares/STM32_Secure_Engine/se_interface_common.c - 1 - PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_common.c - - - Application/BFU/App/sfu_boot.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_boot.c - - - Application/BFU/App/sfu_com_loader.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_com_loader.c - - - Application/BFU/App/sfu_com_trace.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_com_trace.c - - - Application/BFU/App/sfu_error.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_error.c - - - Application/BFU/App/sfu_fwimg_common.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_fwimg_common.c - - - Application/BFU/App/sfu_interface_crypto_scheme.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_interface_crypto_scheme.c - - - Application/BFU/App/sfu_kms.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_kms.c - - - Application/BFU/App/sfu_loader.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_loader.c - - - Application/BFU/App/sfu_new_image.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_new_image.c - - - Application/BFU/App/sfu_test.c - 1 - PARENT-1-PROJECT_LOC/BFU/App/sfu_test.c - - - Application/BFU/Target/sfu_low_level.c - 1 - PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level.c - - - Application/BFU/Target/sfu_low_level_flash.c - 1 - PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash.c - - - Application/BFU/Target/sfu_low_level_flash_ext.c - 1 - PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash_ext.c - - - Application/BFU/Target/sfu_low_level_flash_int.c - 1 - PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash_int.c - - - Application/BFU/Target/sfu_low_level_security.c - 1 - PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_security.c - - - Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c - 1 - PARENT-6-PROJECT_LOC/Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/se_interface.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/se_interface.txt deleted file mode 100644 index ff9b2425..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/se_interface.txt +++ /dev/null @@ -1,41 +0,0 @@ -SE_APP_GetActiveFwInfo -SE_APP_ValidateFw -SE_APP_SVC_Handler -SE_SYS_SaveDisableIrq -SE_SYS_RestoreEnableIrq -SE_KMS_Initialize -SE_KMS_Finalize -SE_KMS_GetInfo -SE_KMS_GetFunctionList -SE_KMS_GetSlotList -SE_KMS_GetSlotInfo -SE_KMS_GetTokenInfo -SE_KMS_GetMechanismInfo -SE_KMS_OpenSession -SE_KMS_CloseSession -SE_KMS_CreateObject -SE_KMS_DestroyObject -SE_KMS_GetAttributeValue -SE_KMS_SetAttributeValue -SE_KMS_FindObjectsInit -SE_KMS_FindObjects -SE_KMS_FindObjectsFinal -SE_KMS_EncryptInit -SE_KMS_Encrypt -SE_KMS_EncryptUpdate -SE_KMS_EncryptFinal -SE_KMS_DecryptInit -SE_KMS_Decrypt -SE_KMS_DecryptUpdate -SE_KMS_DecryptFinal -SE_KMS_DigestInit -SE_KMS_Digest -SE_KMS_DigestUpdate -SE_KMS_DigestFinal -SE_KMS_SignInit -SE_KMS_Sign -SE_KMS_VerifyInit -SE_KMS_Verify -SE_KMS_DeriveKey -SE_KMS_GenerateKeyPair -SE_KMS_GenerateRandom diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/readme.txt deleted file mode 100644 index 7a9c2535..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/readme.txt +++ /dev/null @@ -1,174 +0,0 @@ -/** - @page 1_Image_BFU / Boot and Firmware Update Demo Application - - @verbatim - ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* - * @file readme.txt - * @brief This application shows Boot and Firmware Update example. - ****************************************************************************** - * - * Copyright (c) 2017 STMicroelectronics. All rights reserved. - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - @endverbatim - -@par Application Description - -The Boot (B) and Firmware Update (FU) solution allows the update -of the STM32 microcontroller built-in program with new firmware versions, adding -new features and correcting potential issues. The update process is performed in -a secure way to prevent unauthorized updates. -In addition, Secure Boot (Root of Trust services) checks and activates the STM32 -security mechanisms (if any), and checks the authenticity and integrity of user application -code before every execution to ensure that invalid or malicious code cannot be run. -The Firmware Update application receives the encrypted firmware image, decrypts -it, then checks the authenticity and integrity of the code before installing it. - -The key management services provide cryptographic services to the user -application through the pkcs11 APIs (KEY ID based APIs). User application keys are stored -and can be updated in a secure way (authenticity check, data decryption and data integrity check). - -This example handles 1 firmware image with 1 single slot in FLASH allowing to -maximize the user application size. -As a consequence, some features are not available: -* download a new firmware image from the application -* resume firmware update procedure in case of power off during installation - -To be easily tailorable to 128 Kbytes footprint, SFU_DEBUG_MODE compilation switch is disabled. -As a consequence there is no print on terminal during SBSFU execution. - -For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" -available from the STMicroelectronics microcontroller website www.st.com. - -@par Keywords - -Security, SBSFU, MPU - -@par Directory contents - - - 1_Image_BFU/Core/Src/main.c Main application file - - 1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c HAL MSP module - - 1_Image_BFU/Core/Src/stm32wlxx_it.c STM32 interrupt handlers - - 1_Image_BFU/Core/Inc/app_hw.h Hardware definition for application - - 1_Image_BFU/Core/Inc/main.h Header file for main.c - - 1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h HAL configuration file - - 1_Image_BFU/Core/Inc/stm32wlxx_it.h Header file for stm32wlxx_it.c - - 1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h BSP configuration file - - 1_Image_BFU/BFU/App/sfu_boot.c Secure Boot (SB): entry/exit points and state machine - - 1_Image_BFU/BFU/App/sfu_com_loader.c SBSFU communication module: local loader part - - 1_Image_BFU/BFU/App/sfu_com_trace.c SBSFU communication module: trace part - - 1_Image_BFU/BFU/App/sfu_error.c SBSFU errors management - - 1_Image_BFU/BFU/App/sfu_fwimg_common.c SBSFU image handling: common functionalities/services - - 1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c Crypto scheme implementation based on KMS API - - 1_Image_BFU/BFU/App/sfu_kms.c Key management service blob importation handling - - 1_Image_BFU/BFU/App/sfu_loader.c SBSFU Local Loader - - 1_Image_BFU/BFU/App/sfu_new_image.c SBSFU image handling: manage the new firmware image storage and installation - - 1_Image_BFU/BFU/App/sfu_test.c SBSFU security protection automatic test - - 1_Image_BFU/BFU/App/app_sfu.h Software configuration of SBSFU application - - 1_Image_BFU/BFU/App/sfu_boot.h Header file for sfu_boot.c - - 1_Image_BFU/BFU/App/sfu_com_loader.h Header file for sfu_com_loader.c - - 1_Image_BFU/BFU/App/sfu_com_trace.h Header file for sfu_com_trace.c - - 1_Image_BFU/BFU/App/sfu_def.h General definition for SBSFU application - - 1_Image_BFU/BFU/App/sfu_error.h Header file for sfu_error.c file - - 1_Image_BFU/BFU/App/sfu_fsm_states.h SBSFU FSM states definitions - - 1_Image_BFU/BFU/App/sfu_fwimg_internal.h Internal definitions for firmware image handling (sfu_fwimg_core.c and sfu_fwimg_services.c) - - 1_Image_BFU/BFU/App/sfu_fwimg_regions.h FLASH regions definitions for image handling - - 1_Image_BFU/BFU/App/sfu_fwimg_services.h Header file for sfu_fwimg_services.c - - 1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h Header file for sfu_interface_crypto_scheme.h - - 1_Image_BFU/BFU/App/sfu_kms.h Header file for sfu_kms.c - - 1_Image_BFU/BFU/App/sfu_loader.h Header file for sfu_loader.c - - 1_Image_BFU/BFU/App/sfu_new_image.h Header file for sfu_new_image.c - - 1_Image_BFU/BFU/App/sfu_test.h Header file for sfu_test.c - - 1_Image_BFU/BFU/App/sfu_trace.h Header file for sfu_trace.c - - 1_Image_BFU/BFU/Target/sfu_low_level.c SBSFU general low level interface - - 1_Image_BFU/BFU/Target/sfu_low_level_flash.c SBSFU flash low level interface (wrapper) - - 1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c SBSFU internal flash low level interface - - 1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c SBSFU external flash low level interface - - 1_Image_BFU/BFU/Target/sfu_low_level_security.c SBSFU security low level interface - - 1_Image_BFU/BFU/Target/sfu_low_level.h Header file for general low level interface - - 1_Image_BFU/BFU/Target/sfu_low_level_flash.h Header file for flash low level interface (wrapper) - - 1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h Header file for internal flash low level interface - - 1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h Header file for external flash low level interface - - 1_Image_BFU/BFU/Target/sfu_low_level_security.h Header file for security low level interface - -@par Hardware and Software environment - - - This example runs on STM32WL55xx devices. - - This example has been tested with NUCLEO-WL55JC RevC board and can be - easily tailored to any other supported device and development board. - - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware - is a feature provided by STM32Cube programmer available on www.st.com. - - This example is linked with SE_Core binary generated by Secure Engine Core binary generation project. - - This example needs a terminal emulator. - - Microsoft Windows has a limitation whereby paths to files and directories cannot - be longer than 256 characters. Paths to files exceeding that limits cause tools (e.g. compilers, - shell scripts) to fail reading from or writing to such files. - As a workaround, it is advised to use the subst.exe command from within a command prompt to set - up a local drive out of an existing directory on the hard drive, such as: - C:\> subst X: \Firmware - -@par How to use it ? - -Several steps to run BFU application : - -1. Compile projects in the following order. This is mandatory as each project requests some objects - generated by the compilation of the previous one: - - 1_Image_SECoreBin (see also SECoreBin/readme.txt) - - 1_Image_BFU - - 1_Image_UserApp (see also UserApp/readme.txt) - -2. Before loading BFU image into the target, please ensure with STM32CubeProgrammer available on www.st.com that - the following are valid for the device: - - RDP Level 0 - - Write Protection disabled on all FLASH pages - - Chip has been erased - -3. Use a terminal emulator (Tera Term for example, open source free software terminal emulator - that can be downloaded from https://osdn.net/projects/ttssh2/) for UART connection with the board. - Support of YMODEM protocol is required. Serial port configuration should be : - - Baud rate = 115200 - - Data = 8 bits - - Parity = none - - Stop = 1 bit - - Flow control = none - -4. Load BFU image into target memory with your preferred toolchain or STM32CubeProgammer. - -5. Once the BFU software is downloaded, power cycle the board (unplug/plug USB cable) : the BFU - application starts and configures the security mechanisms if some of them are enabled. - -6. [If RDP is enabled] Power cycle the board a second time (unplug/plug the USB cable): the BFU application starts with - the configured securities turned on and the Tera Term connection is possible. - Caution: Make sure to use an up-to-date version of ST-LINK firmware else BFU may not start. - -7. At startup (Power On or Reset button pushed) : - - Green LED blinks every 3 seconds when a local download is waited. - - Green LED blinks every 250 ms in case of error in option bytes configuration. - - 'C' is displayed when BFU is ready for a firmware image download. To be easily tailorable to 128 Kbytes footprint, - SFU_DEBUG_MODE compilation switch is disabled. As a consequence there is no print on terminal during - BFU execution. - -8. Send the user encrypted firmware file (\1_Image\1_Image_UserApp\Binary\UserApp.sfb) with Tera Term - by using menu "File > Transfer > YMODEM > Send..." - -Note1 : Press User push-button (B1) at reset to force a local download if an application is already installed. -Note2 : The following steps enable the protections disabled by default: - - Comment "SECBOOT_DISABLE_SECURITY_IPS" in app_sfu.h. This will enable RDP, WRP, DAP, DMA, IWDG protections - as well as attack surface reduction with MPU. - - As TAMPER detection can be very sensitive, the protection remains disabled by default. - Uncomment "SFU_TAMPER_PROTECT_ENABLE" in app_sfu.h to enable it. - - In Linker_Common, update the mapping by: - - Renaming "mapping_fwimg.icf" to "mapping_fwimg_no_sec.icf". - - Renaming "mapping_sbsfu.icf" to "mapping_sbsfu_no_sec.icf". - - Renaming "mapping_fwimg_sec.icf" to "mapping_fwimg.icf". - - Renaming "mapping_sbsfu_sec.icf" to "mapping_sbsfu.icf". - These features achieve an attack surface reduction but will not make it possible to protect secrets. -Note3 : for Linux users Minicom can be used but to do so you need to compile the SBSFU project with the MINICOM_YMODEM switch enabled (app_sfu.h) - - *

      © COPYRIGHT STMicroelectronics

      - */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/Project.ewp deleted file mode 100644 index 1df6658c..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/Project.ewp +++ /dev/null @@ -1,1056 +0,0 @@ - - - 2 - - STM32WL55JC_Nucleo_1_Image_KMS_Blob - - ARM - - 1 - - General - 3 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 34 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 10 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - cmd /C "cmd /C $PROJ_DIR$\postbuild.bat "$PROJ_DIR$" "KMS_Blob" 1 " - - - - ILINK - 0 - - 21 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - - Doc - - $PROJ_DIR$\..\readme.txt - - - - Application - - User - - $PROJ_DIR$\..\Src\kms_blob_example_keys.c - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx deleted file mode 100644 index 7710f10c..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx +++ /dev/null @@ -1,422 +0,0 @@ - - - - 2.1 - -
      ### uVision Project, (C) Keil Software
      - - - - STM32WL55JC_Nucleo_1_Image_KMS_Blob - 0x4 - ARM-ADS - 6120000::V6.12::.\ARMCLANG - 1 - - - STM32WL55JCIx:CM4 - STMicroelectronics - Keil.STM32WLxx_DFP.1.0.4 - http://www.keil.com/pack - IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) - 0 - $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h - - - - - - - - - - $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\STM32WL55JC_Nucleo\Exe\ - KMS_blob - 1 - 0 - 0 - 1 - 1 - - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 1 - 1 - fromelf #L --bin --output=$L../../@L.bin - postbuild.bat . @L 1 - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 0 - - - SARMCM3.DLL - -REMAP -MPU - DCM.DLL - -pCM4 - SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4101 - - 1 - BIN\UL2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M4" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 1 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 1 - 0x8000000 - 0x40000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x8000000 - 0x40000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 0 - 0x0 - 0x0 - - - - - - 1 - 4 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 0 - 1 - 0 - 0 - 5 - 3 - 0 - 0 - 0 - 0 - 0 - - - USE_HAL_DRIVER,STM32WL55xx,CORE_CM4 - - ../Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Platform;../../1_Image_SECoreBin/Inc - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - 0 - 0 - 0 - - - - KMS_Blob.sct - - - --diag_suppress L6305W - - - - - - - - Doc - - - readme.txt - 5 - ../readme.txt - - - - - Application/User - - - kms_blob_example_keys.c - 1 - ../Src/kms_blob_example_keys.c - - - - - ::CMSIS - - - - - - - - - - - - - - - - - - -
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/.cproject deleted file mode 100644 index 5b0e678a..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/.cproject +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/postbuild.sh b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/postbuild.sh deleted file mode 100644 index 82dd9adb..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/postbuild.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash - -#Post build for SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 -# arg1 is the build directory -# arg2 is the bin file path+name without extension -# arg3 is the version - -projectdir=$1 -execname=$2 -version=$3 - -userAppBinary=$projectdir"/../Binary" -bin=$execname".bin" - -kmsu=$userAppBinary"/"$execname".kmsu" -kmsb=$userAppBinary"/"$execname".kmsb" -sign=$userAppBinary"/"$execname".sign" - -iv=$userAppBinary"/iv.bin" -oemkey=$userAppBinary"/OEM_KEY_COMPANY1_key_AES_CBC.bin" -ecckey=$userAppBinary"/ECCKEY.txt" - -current_directory=`pwd` -cd $1/../../../../../../Middlewares/ST/STM32_Secure_Engine/Utilities/KeysAndImages -basedir=`pwd` -cd $current_directory -# test if window executable usable -prepareimage=$basedir"/win/prepareimage/prepareimage.exe" -uname | grep -i -e windows -e mingw - -if [ $? == 0 ] && [ -e "$prepareimage" ]; then - echo "prepareimage with windows executable" - cmd="" -else - # line for python - echo "prepareimage with python script" - prepareimage=$basedir/prepareimage.py - cmd="python" -fi - -echo "$cmd $prepareimage" > $1/output.txt -# Make sure we have a Binary sub-folder in UserApp folder -if [ ! -e $userAppBinary ]; then -mkdir $userAppBinary -fi - -command=$cmd" "$prepareimage" enc -k "$oemkey" -i "$iv" "$bin" "$kmsu -echo $command -$command >> "$projectdir"/output.txt -ret=$? -if [ $ret == 0 ]; then -# -p 16 indicates that the input file must be a multiple of the AES block size (16 bytes). Padding is done before computing the sha256 if needed. - command=$cmd" "$prepareimage" sha256 "$bin" "$sign" -p 16" - echo $command - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret == 0 ]; then - command=$cmd" "$prepareimage" pack -k "$ecckey" -m "KMSB" -r 28 -v "$version" -i "$iv" -f "$kmsu" -t "$sign" -o 320 "$kmsb - echo $command - $command >> $projectdir"/output.txt" - ret=$? - fi -fi - -if [ $ret == 0 ]; then - rm $sign - rm $kmsu - exit 0 -else - echo "$command : failed" >> $projectdir"/output.txt" - echo $command : failed - read -n 1 -s - exit 1 -fi \ No newline at end of file diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/Project.ewp deleted file mode 100644 index 759b7c04..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/Project.ewp +++ /dev/null @@ -1,1184 +0,0 @@ - - - 2 - - STM32WL55JC_Nucleo_1_Image_SECoreBin - - ARM - - 1 - - General - 3 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 34 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 10 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /C "cmd /C $PROJ_DIR$\prebuild.bat "$PROJ_DIR$" " - - - - - ILINK - 0 - - 21 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - - Doc - - $PROJ_DIR$\..\readme.txt - - - - Application - - User - - $PROJ_DIR$\..\Src\se_low_level.c - - - $PROJ_DIR$\..\Src\kms_low_level.c - - - $PROJ_DIR$\..\Src\nvms_low_level.c - - - $PROJ_DIR$\..\Src\ca_low_level.c - - - - - Drivers - - STM32WLxx_HAL_Driver - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cryp.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cryp_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pka.c - - - - - Middlewares - - STM32_Secure_Engine - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_bootinfo.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_callgate.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_exception.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_fwimg.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_startup.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_user_application.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_utils.c - - - - STM32_Key_Management_Services - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_der_x962.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_ecc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_entry.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_init.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_mem.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_objects.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_platf_objects.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_digest.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_dyn_obj.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_enc_dec.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_key_mgt.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_nvm_storage.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_sign_verify.c - - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Interface\CryptoApi\ca_core.c - - - - Third_Party - - mbed-crypto - - $PROJ_DIR$\..\..\..\..\..\..\Middlewares\Third_Party\mbed-crypto\library\sha256.c - - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat deleted file mode 100644 index 30d6619d..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat +++ /dev/null @@ -1,122 +0,0 @@ -::Post build for SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM -:: arg1 is the build directory -:: arg2 is the elf file path+name -:: arg3 is the bin file path+name -:: arg4 is the firmware Id (1/2/3) -:: arg5 is the version -:: arg6 when present forces "bigelf" generation -@echo off -set "projectdir=%1" -set "execname=%~n3" -set "elf=%2" -set "bin=%3" -set "fwid=%4" -set "version=%5" - -set "SBSFUBootLoader=%~d0%~p0\\..\\.." -::The default installation path of the Cube Programmer tool is: "C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" -::If you installed it in another location, please update the %programmertool% variable below accordingly. -set "programmertool="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" -set "userAppBinary=%projectdir%\\..\\Binary\\" - -set "sfu=%userAppBinary%\\%execname%.sfu" -set "sfb=%userAppBinary%\\%execname%.sfb" -set "sign=%userAppBinary%\\%execname%.sign" -set "headerbin=%userAppBinary%\\%execname%sfuh.bin" -set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" -set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" - - -set "nonce=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\nonce.bin" -set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" -set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\project.out" -set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_GCM.bin" -set "magic=SFU%fwid%" - -::comment this line to force python -::python is used if windows executable not found -pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages -set basedir=%cd% -popd -goto exe: -goto py: -:exe -::line for window executable -echo Postbuild with windows executable -set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" -set "python=" -if exist %prepareimage% ( -goto postbuild -) -:py -::line for python -echo Postbuild with python script -set "prepareimage=%basedir%\\prepareimage.py" -set "python=python " -:postbuild - -::Make sure we have a Binary sub-folder in UserApp folder -if not exist "%userAppBinary%" ( -mkdir "%userAppBinary%" -) - -::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf -if exist %elfbackup% ( -fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" -) - -set "command=%python%%prepareimage% enc -k %oemkey% -n %nonce% %bin% %sfu% > %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -set "command=%python%%prepareimage% sign -k %oemkey% -n %nonce% %bin% %sign% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -set "command=%python%%prepareimage% pack -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% %sfb% -o 512 >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error -set "command=%python%%prepareimage% header -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% -o 512 %headerbin% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - - -:bigelf -IF "%~6"=="" goto :finish -echo "Generating the global elf file (SBSFU and userApp)" -echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt -set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error -set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -:finish -::backup and clean up the intermediate file -del %sign% -del %sfu% -del %headerbin% - -exit 0 - -:error -echo "%command% : failed" >> %projectdir%\\output.txt -:: remove the elf to force the regeneration -if exist %elf%( - del %elf% -) -if exist %elfbackup%( - del %elfbackup% -) -echo %command% : failed - -pause -exit 1 - -:nothingtodo -exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat deleted file mode 100644 index 0fb75e6d..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat +++ /dev/null @@ -1,119 +0,0 @@ -::Post build for SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 -:: arg1 is the build directory -:: arg2 is the elf file path+name -:: arg3 is the bin file path+name -:: arg4 is the firmware Id (1/2/3) -:: arg5 is the version -:: arg6 when present forces "bigelf" generation -@echo off -set "projectdir=%1" -set "execname=%~n3" -set "elf=%2" -set "bin=%3" -set "fwid=%4" -set "version=%5" - -set "SBSFUBootLoader=%~d0%~p0\\..\\.." -::The default installation path of the Cube Programmer tool is: "C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" -::If you installed it in another location, please update the %programmertool% variable below accordingly. -set "programmertool="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" -set "userAppBinary=%projectdir%\\..\\Binary\\" - -set "sfb=%userAppBinary%\\%execname%.sfb" -set "sign=%userAppBinary%\\%execname%.sign" -set "headerbin=%userAppBinary%\\%execname%sfuh.bin" -set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" -set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" - -set "oemkey=" -set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" -set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\project.out" -set "magic=SFU%fwid%" - -::comment this line to force python -::python is used if windows executable not found -pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages -set basedir=%cd% -popd -goto exe: -goto py: -:exe -::line for window executable -echo Postbuild with windows executable -set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" -set "python=" -if exist %prepareimage% ( -goto postbuild -) -:py -::line for python -echo Postbuild with python script -set "prepareimage=%basedir%\\prepareimage.py" -set "python=python " -:postbuild - -::Make sure we have a Binary sub-folder in UserApp folder -if not exist "%userAppBinary%" ( -mkdir "%userAppBinary%" > %projectdir%\output.txt 2>&1 -IF %ERRORLEVEL% NEQ 0 goto :error -) - -::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf -if exist %elfbackup% ( -fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" -) - -:: no encryption -set "command=%python%%prepareimage% sha256 %bin% %sign% > %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -:: no encryption so pack the binary file - -set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% %sfb% -o 512 >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error -set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% -o 512 %headerbin% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - - -:bigelf -IF "%~6"=="" goto :finish -echo "Generating the global elf file (SBSFU and userApp)" -echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt -set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error -set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -:finish -::backup and clean up the intermediate file -del %sign% -del %sfu% -del %headerbin% - -exit 0 - -:error -echo "%command% : failed" >> %projectdir%\\output.txt -:: remove the elf to force the regeneration -if exist %elf%( - del %elf% -) -if exist %elfbackup%( - del %elfbackup% -) -echo %command% : failed - -pause -exit 1 - -:nothingtodo -exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat deleted file mode 100644 index db7e4155..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat +++ /dev/null @@ -1,121 +0,0 @@ -::Post build for SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 -:: arg1 is the build directory -:: arg2 is the elf file path+name -:: arg3 is the bin file path+name -:: arg4 is the firmware Id (1/2/3) -:: arg5 is the version -:: arg6 when present forces "bigelf" generation -@echo off -set "projectdir=%1" -set "execname=%~n3" -set "elf=%2" -set "bin=%3" -set "fwid=%4" -set "version=%5" - -set "SBSFUBootLoader=%~d0%~p0\\..\\.." -::The default installation path of the Cube Programmer tool is: "C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" -::If you installed it in another location, please update the %programmertool% variable below accordingly. -set "programmertool="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" -set "userAppBinary=%projectdir%\\..\\Binary\\" - -set "sfu=%userAppBinary%\\%execname%.sfu" -set "sfb=%userAppBinary%\\%execname%.sfb" -set "sign=%userAppBinary%\\%execname%.sign" -set "headerbin=%userAppBinary%\\%execname%sfuh.bin" -set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" -set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" - -set "iv=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\iv.bin" -set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" -set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\project.out" -set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_CBC.bin" -set "magic=SFU%fwid%" - -::comment this line to force python -::python is used if windows executable not found -pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages -set basedir=%cd% -popd -goto exe: -goto py: -:exe -::line for window executable -echo Postbuild with windows executable -set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" -set "python=" -if exist %prepareimage% ( -goto postbuild -) -:py -::line for python -echo Postbuild with python script -set "prepareimage=%basedir%\\prepareimage.py" -set "python=python " -:postbuild - -::Make sure we have a Binary sub-folder in UserApp folder -if not exist "%userAppBinary%" ( -mkdir "%userAppBinary%" -) - -::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf -if exist %elfbackup% ( -fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" -) - -set "command=%python%%prepareimage% enc -k %oemkey% -i %iv% %bin% %sfu% > %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -set "command=%python%%prepareimage% sha256 %bin% %sign% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% %sfb% -o 512 >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error -set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% -o 512 %headerbin% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - - -:bigelf -IF "%~6"=="" goto :finish -echo "Generating the global elf file (SBSFU and userApp)" -echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt -set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error -set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" -%command% -IF %ERRORLEVEL% NEQ 0 goto :error - -:finish -::backup and clean up the intermediate file -del %sign% -del %sfu% -del %headerbin% - -exit 0 - -:error -echo "%command% : failed" >> %projectdir%\\output.txt -:: remove the elf to force the regeneration -if exist %elf%( - del %elf% -) -if exist %elfbackup%( - del %elfbackup% -) -echo %command% : failed - -pause -exit 1 - -:nothingtodo -exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf deleted file mode 100644 index b97f0115..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf +++ /dev/null @@ -1,24 +0,0 @@ -/*###ICF### Set of symbols used in SE and SB_SFU projects ****/ - -define memory mem with size = 4G; - -/******************************************************************************/ -/* Include of SE symbols file */ -/* (Project>Options>Linker>Extra Options --config_search option is used to */ -/* specify the the directory to search for include files */ -/******************************************************************************/ -include "mapping_sbsfu.icf"; -include "mapping_fwimg.icf"; - -initialize by copy { readwrite }; -do not initialize { section .noinit, section BOOTINFO_DATA}; - -/******************************************************************************/ -/* placement instructions */ -/******************************************************************************/ -place at address mem:__ICFEDIT_SE_CallGate_region_ROM_start__ { readonly section .SE_CallGate_Code }; -place at address mem:__ICFEDIT_SE_Startup_region_ROM_start__ { readonly section .SE_Startup_Code}; -place in SE_CODE_NOKEY_ROM_region {readonly}; -place in SE_Key_ROM_region { readonly section .SE_embedded_Keys }; -keep { section .SE_embedded_Keys }; -place in SE_RAM_region {readwrite, section BOOTINFO_DATA}; diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/se_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/se_low_level.h deleted file mode 100644 index 2857e3e6..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/se_low_level.h +++ /dev/null @@ -1,191 +0,0 @@ -/** - ****************************************************************************** - * @file se_low_level.h - * @author MCD Application Team - * @brief This file contains definitions for Secure Engine low level interface - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef SE_LOW_LEVEL_H -#define SE_LOW_LEVEL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "se_def.h" - -/* Secure Engine needs to know the slots configuration for the Read/Write services in protected area - (see @ref SE_IMG_Write, see @ref SE_IMG_Read) */ -#include "sfu_fwimg_regions.h" - -#include "stm32wlxx_hal.h" - -/** @addtogroup SE - * @{ - */ - -/** @addtogroup SE_HARDWARE - * @{ - */ - -/** @defgroup SE_HARDWARE_Exported_Constants Exported Constants - * @{ - */ -/** - * @brief flash handling constants: these constants are used in se_fwimg.c - */ - -/** - * @} - */ - -/** @defgroup SE_HARDWARE_Exported_Macros Exported Macros - * @{ - */ - -/** @defgroup SE_HARDWARE_Exported_Macros_CRC CRC Settings - * @{ - */ - -/** - * @brief Set CRC 32 of the BootInfoTypeDef pointer passed as parameter - * The CRC is computed with the structure without its CRC field and the length is provided to SE_CRC_Calculate in - * 32-bit word. - * Please note that this works only if the CRC field is kept as the last uint32_t of the SE_BootInfoTypeDef structure. - */ -#define SE_BOOT_CONFIG_SET_CRC_32(x) \ - do{ \ - (x)->CRC32 = SE_CRC_Calculate ((uint32_t*)(x), (sizeof(SE_BootInfoTypeDef)-sizeof(uint32_t))/sizeof(uint32_t));\ - }while(0) - -/** - * @brief Set CRC of the BootInfoTypeDef pointer passed as parameter - */ -#define SE_BOOT_CONFIG_SET_CRC(x) SE_BOOT_CONFIG_SET_CRC_32(x) - -/** - * @} - */ - -/** @defgroup SE_HARDWARE_Exported_Macros_CodeIsolation Code Isolation Settings - * @brief These settings configure the way the Secure Engine is isolated from the rest of the code. - * @{ - */ - -/* == Code isolation : FIREWALL example ==*/ -#define ENTER_PROTECTED_AREA() do { /* do nothing */; } while(0) -#define EXIT_PROTECTED_AREA() do { /* do nothing */; } while(0) - -/* == Code isolation : MPU example ==*/ -/** - * This switch enables the Secure Engine isolation based on the MPU usage. - * This switch must be enabled if the STM32 platform in use does not have a Firewall. - * This switch cannot be enabled if the example is provided with Firewall isolation. - */ - -/** @addtogroup SE_LOW_LEVEL_Exported_Functions - * @{ - */ -void SE_LL_CORE_Cleanup(void); - -/** - * @} - */ - -/** - * @} - */ - -/** @addtogroup SE_HARDWARE_Exported_Functions - * @{ - */ - -/** @addtogroup SE_HARDWARE_Exported_CRC_Functions - * @{ - */ -SE_ErrorStatus SE_LL_CRC_Config(void); -SE_ErrorStatus SE_LL_CRC_Init(void); -SE_ErrorStatus SE_LL_CRC_DeInit(void); -uint32_t SE_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t uBufferLength); - -/** - * @} - */ - -/** @addtogroup SE_HARDWARE_Exported_FLASH_Functions - * @{ - */ -SE_ErrorStatus SE_LL_FLASH_Erase(uint8_t *pStart, uint32_t Length); -SE_ErrorStatus SE_LL_FLASH_Write(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); -SE_ErrorStatus SE_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); - -void NMI_Handler(void); -void HardFault_Handler(void); -/** - * @} - */ - -/** @addtogroup SE_HARDWARE_Exported_FLASH_EXT_Functions - * @{ - */ -SE_ErrorStatus SE_LL_FLASH_EXT_Decrypt_Init(SE_FwRawHeaderTypeDef *pxSE_Metadata); -/** - * @} - */ - -/** @addtogroup SE_BUFFER_CHECK_Exported_RAM_Functions - * @{ - */ - -SE_ErrorStatus SE_LL_Buffer_in_ram(void *pBuff, uint32_t Length); -SE_ErrorStatus SE_LL_Buffer_in_SBSFU_ram(const void *pBuff, uint32_t Length); -SE_ErrorStatus SE_LL_Buffer_part_of_SE_ram(const void *pBuff, uint32_t Length); -SE_ErrorStatus SE_LL_Buffer_part_of_SE_rom(const void *pBuff, uint32_t Length); -/** - * @} - */ - -/** @addtogroup SE_BUFFER_CHECK_Exported_RAM_Functions - * @{ - */ - -SE_ErrorStatus SE_LL_Save_Disable_Irq(uint32_t *pIrqState, uint32_t IrqStateNb); -SE_ErrorStatus SE_LL_Restore_Enable_Irq(uint32_t *pIrqState, uint32_t IrqStateNb); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* SE_LOW_LEVEL_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/Project.uvoptx deleted file mode 100644 index 43e75521..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/Project.uvoptx +++ /dev/null @@ -1,730 +0,0 @@ - - - - 1.0 - -
      ### uVision Project, (C) Keil Software
      - - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - STM32WL55JC_Nucleo_1_Image_SECoreBin - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 18 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 6 - - - - - - - - - - - STLink\ST-LINKIII-KEIL_SWO.dll - - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - ST-LINKIII-KEIL_SWO - -U001F00313038511234333935 -O206 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4.FLM -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0) - - - 0 - UL2CM3 - UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) - - - - - 0 - 0 - 201 - 1 -
      134218244
      - 0 - 0 - 0 - 0 - 0 - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c - - \\SECoreBin\../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c\201 -
      -
      - - - 1 - 0 - 0x20005AF8 - 0 - - - - 0 - - - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - -
      -
      - - - Application/MDK-ARM - 0 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - .\data_init.c - data_init.c - 0 - 0 - - - - - Application/User - 0 - 0 - 0 - 0 - - 2 - 2 - 1 - 0 - 0 - 0 - ../Src/ca_low_level.c - ca_low_level.c - 0 - 0 - - - 2 - 3 - 1 - 0 - 0 - 0 - ../Src/kms_low_level.c - kms_low_level.c - 0 - 0 - - - 2 - 4 - 1 - 0 - 0 - 0 - ../Src/nvms_low_level.c - nvms_low_level.c - 0 - 0 - - - 2 - 5 - 1 - 0 - 0 - 0 - ../Src/se_low_level.c - se_low_level.c - 0 - 0 - - - - - Doc - 1 - 0 - 0 - 0 - - 3 - 6 - 5 - 0 - 0 - 0 - ../readme.txt - readme.txt - 0 - 0 - - - - - Drivers/STM32WLxx_HAL_Driver - 0 - 0 - 0 - 0 - - 4 - 7 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - stm32wlxx_hal_crc.c - 0 - 0 - - - 4 - 8 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - stm32wlxx_hal_crc_ex.c - 0 - 0 - - - 4 - 9 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c - stm32wlxx_hal_cryp.c - 0 - 0 - - - 4 - 10 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c - stm32wlxx_hal_cryp_ex.c - 0 - 0 - - - 4 - 11 - 1 - 0 - 0 - 0 - ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_dma.c - stm32wlxx_hal_dma.c - 0 - 0 - - - 4 - 12 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - stm32wlxx_hal_flash.c - 0 - 0 - - - 4 - 13 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - stm32wlxx_hal_flash_ex.c - 0 - 0 - - - 4 - 14 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c - stm32wlxx_hal_pka.c - 0 - 0 - - - - - Middlewares/STM32_Secure_Engine - 0 - 0 - 0 - 0 - - 5 - 15 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_bootinfo.c - se_bootinfo.c - 0 - 0 - - - 5 - 16 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c - se_callgate.c - 0 - 0 - - - 5 - 17 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c - se_exception.c - 0 - 0 - - - 5 - 18 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c - se_fwimg.c - 0 - 0 - - - 5 - 19 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c - se_startup.c - 0 - 0 - - - 5 - 20 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c - se_user_application.c - 0 - 0 - - - 5 - 21 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c - se_utils.c - 0 - 0 - - - - - Middlewares/STM32_Key_Management_Services - 0 - 0 - 0 - 0 - - 6 - 22 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c - ca_core.c - 0 - 0 - - - 6 - 23 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c - kms_der_x962.c - 0 - 0 - - - 6 - 24 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c - kms_digest.c - 0 - 0 - - - 6 - 25 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c - kms_dyn_obj.c - 0 - 0 - - - 6 - 26 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c - kms_ecc.c - 0 - 0 - - - 6 - 27 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c - kms_enc_dec.c - 0 - 0 - - - 6 - 28 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c - kms_entry.c - 0 - 0 - - - 6 - 29 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c - kms_init.c - 0 - 0 - - - 6 - 30 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c - kms_key_mgt.c - 0 - 0 - - - 6 - 31 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c - kms_mem.c - 0 - 0 - - - 6 - 32 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c - kms_nvm_storage.c - 0 - 0 - - - 6 - 33 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c - kms_objects.c - 0 - 0 - - - 6 - 34 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c - kms_platf_objects.c - 0 - 0 - - - 6 - 35 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c - kms_sign_verify.c - 0 - 0 - - - - - Middlewares/Third_Party/mbed-crypto - 0 - 0 - 0 - 0 - - 7 - 36 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/Third_Party/mbed-crypto/library/platform_util.c - platform_util.c - 0 - 0 - - - 7 - 37 - 1 - 0 - 0 - 0 - ../../../../../../Middlewares/Third_Party/mbed-crypto/library/sha256.c - sha256.c - 0 - 0 - - - - - ::CMSIS - 0 - 0 - 0 - 1 - - -
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/Project.uvprojx deleted file mode 100644 index 0720d5dd..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/Project.uvprojx +++ /dev/null @@ -1,624 +0,0 @@ - - - - 2.1 - -
      ### uVision Project, (C) Keil Software
      - - - - STM32WL55JC_Nucleo_1_Image_SECoreBin - 0x4 - ARM-ADS - 6120000::V6.12::.\ARMCLANG - 1 - - - STM32WL55JCIx:CM4 - STMicroelectronics - Keil.STM32WLxx_DFP.1.0.4 - http://www.keil.com/pack - IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) - 0 - $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h - - - - - - - - - - $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\STM32WL55JC_Nucleo\Exe\ - SECoreBin - 1 - 0 - 0 - 1 - 1 - - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 1 - - prebuild.bat . - 0 - 0 - 0 - 0 - - - 1 - 0 - fromelf #L --bin --output=$L@L.bin - - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 0 - - - SARMCM3.DLL - -REMAP -MPU - DCM.DLL - -pCM4 - SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4101 - - 1 - BIN\UL2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M4" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 1 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 1 - 0x8000000 - 0x40000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x8000000 - 0x40000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 0 - 0x0 - 0x0 - - - - - - 1 - 7 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 0 - 1 - 0 - 0 - 5 - 3 - 0 - 0 - 0 - 0 - 0 - - - USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED,MBEDTLS_CONFIG_FILE=<mbed_crypto_config.h>,IT_MANAGEMENT_DISABLED - - .;../Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../../../../../Middlewares/ST/STM32_Secure_Engine/Key;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules;../../../../../../Middlewares/Third_Party/mbed-crypto/include;../../1_Image_BFU/BFU/App;../../1_Image_BFU/BFU/Target;../../Linker_Common/MDK-ARM - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - - - - SECoreBin.sct - - - --entry=SE_CallGate ---diag_suppress L6404W ---diag_suppress L6314W - - - - - - - - Application/MDK-ARM - - - data_init.c - 1 - .\data_init.c - - - - - Application/User - - - ca_low_level.c - 1 - ../Src/ca_low_level.c - - - kms_low_level.c - 1 - ../Src/kms_low_level.c - - - nvms_low_level.c - 1 - ../Src/nvms_low_level.c - - - se_low_level.c - 1 - ../Src/se_low_level.c - - - - - Doc - - - readme.txt - 5 - ../readme.txt - - - - - Drivers/STM32WLxx_HAL_Driver - - - stm32wlxx_hal_crc.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - - - stm32wlxx_hal_crc_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - - - stm32wlxx_hal_cryp.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c - - - stm32wlxx_hal_cryp_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c - - - stm32wlxx_hal_dma.c - 1 - ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_dma.c - - - stm32wlxx_hal_flash.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - - - stm32wlxx_hal_flash_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - - - stm32wlxx_hal_pka.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c - - - - - Middlewares/STM32_Secure_Engine - - - se_bootinfo.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_bootinfo.c - - - se_callgate.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c - - - se_exception.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c - - - se_fwimg.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c - - - se_startup.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c - - - se_user_application.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c - - - se_utils.c - 1 - ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c - - - - - Middlewares/STM32_Key_Management_Services - - - ca_core.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c - - - kms_der_x962.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c - - - kms_digest.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c - - - kms_dyn_obj.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c - - - kms_ecc.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c - - - kms_enc_dec.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c - - - kms_entry.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c - - - kms_init.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c - - - kms_key_mgt.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c - - - kms_mem.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c - - - kms_nvm_storage.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c - - - kms_objects.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c - - - kms_platf_objects.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c - - - kms_sign_verify.c - 1 - ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c - - - - - Middlewares/Third_Party/mbed-crypto - - - platform_util.c - 1 - ../../../../../../Middlewares/Third_Party/mbed-crypto/library/platform_util.c - - - sha256.c - 1 - ../../../../../../Middlewares/Third_Party/mbed-crypto/library/sha256.c - - - - - ::CMSIS - - - - - - - - - - - - - - - - - - -
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct deleted file mode 100644 index 679a84f3..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct +++ /dev/null @@ -1,29 +0,0 @@ -#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0plus -E -xc -; ************************************************************* -; *** Scatter-Loading Description File generated by uVision *** -; ************************************************************* -#include "..\..\Linker_Common\MDK-ARM\mapping_sbsfu.h" -#include "..\..\Linker_Common\MDK-ARM\mapping_fwimg.h" - - -; *** regions needed by SE_CoreBin project *** -LR_SE SE_CODE_REGION_ROM_START { - SE_CallGate_region_ROM SE_CALLGATE_REGION_ROM_START FIXED SE_CALLGATE_REGION_ROM_SIZE { - *(.SE_CallGate_Code) - } - SE_Key_region_ROM SE_KEY_REGION_ROM_START FIXED SE_KEY_REGION_ROM_SIZE { - *(.SE_embedded_Keys) - } - SE_Startup_region_ROM SE_STARTUP_REGION_ROM_START FIXED { - *(.SE_Startup_Code) - } - SE_Code_NoKey_region SE_CODE_NOKEY_REGION_ROM_START FIXED SE_ROM_REGION_SIZE{ - .ANY (+RO) - } - SE_region_RAM SE_REGION_RAM_STACK_TOP SE_RAM_REGION_SIZE { - .ANY (+RW +ZI) - } - SE_region_RAM_Boot +0 { - *(BOOTINFO_DATA) - } -} diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/.cproject deleted file mode 100644 index a01ed63f..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/.cproject +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/.project deleted file mode 100644 index 52199163..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/.project +++ /dev/null @@ -1,206 +0,0 @@ - - - 1_Image_SECoreBin - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - com.st.stm32cube.ide.mcu.MCUProjectNature - org.eclipse.cdt.core.cnature - com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature - com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature - com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature - com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature - com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature - com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature - com.st.stm32cube.ide.mcu.MCURootProjectNature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - - - Doc/readme.txt - 1 - $%7BPARENT-1-PROJECT_LOC%7D/readme.txt - - - Application/User/ca_low_level.c - 1 - $%7BPARENT-1-PROJECT_LOC%7D/Src/ca_low_level.c - - - Application/User/kms_low_level.c - 1 - $%7BPARENT-1-PROJECT_LOC%7D/Src/kms_low_level.c - - - Application/User/nvms_low_level.c - 1 - $%7BPARENT-1-PROJECT_LOC%7D/Src/nvms_low_level.c - - - Application/User/se_low_level.c - 1 - $%7BPARENT-1-PROJECT_LOC%7D/Src/se_low_level.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cryp.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cryp_ex.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pka.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c - - - Middlewares/STM32_Key_Management_Services/ca_core.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c - - - Middlewares/STM32_Key_Management_Services/kms_der_x962.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c - - - Middlewares/STM32_Key_Management_Services/kms_digest.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c - - - Middlewares/STM32_Key_Management_Services/kms_dyn_obj.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c - - - Middlewares/STM32_Key_Management_Services/kms_ecc.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c - - - Middlewares/STM32_Key_Management_Services/kms_enc_dec.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c - - - Middlewares/STM32_Key_Management_Services/kms_entry.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c - - - Middlewares/STM32_Key_Management_Services/kms_init.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c - - - Middlewares/STM32_Key_Management_Services/kms_key_mgt.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c - - - Middlewares/STM32_Key_Management_Services/kms_mem.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c - - - Middlewares/STM32_Key_Management_Services/kms_nvm_storage.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c - - - Middlewares/STM32_Key_Management_Services/kms_objects.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c - - - Middlewares/STM32_Key_Management_Services/kms_platf_objects.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c - - - Middlewares/STM32_Key_Management_Services/kms_sign_verify.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c - - - Middlewares/STM32_Secure_Engine/se_bootinfo.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_bootinfo.c - - - Middlewares/STM32_Secure_Engine/se_callgate.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c - - - Middlewares/STM32_Secure_Engine/se_exception.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c - - - Middlewares/STM32_Secure_Engine/se_fwimg.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c - - - Middlewares/STM32_Secure_Engine/se_startup.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c - - - Middlewares/STM32_Secure_Engine/se_user_application.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c - - - Middlewares/STM32_Secure_Engine/se_utils.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c - - - Middlewares/Third_Party/mbed-crypto/sha256.c - 1 - $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/Third_Party/mbed-crypto/library/sha256.c - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.sh b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.sh deleted file mode 100644 index db7fe674..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash - -#Post build for SECBOOT_AES128_GCM_WITH_AES128_GCM -# arg1 is the build directory -# arg2 is the elf file path+name -# arg3 is the bin file path+name -# arg4 is the firmware Id (1/2/3) -# arg5 is the version -# arg6 when present forces "bigelf" generation -projectdir=$1 -FileName=${3##*/} -execname=${FileName%.*} -elf=$2 -bin=$3 -version=$5 - -SecureEngine=${0%/*} - -userAppBinary=$projectdir"/../Binary" - -sfu=$userAppBinary"/"$execname".sfu" -sfb=$userAppBinary"/"$execname".sfb" -sign=$userAppBinary"/"%execname".sign" -headerbin=$userAppBinary"/"$execname"sfuh.bin" -bigbinary=$userAppBinary"/BFU_"$execname".bin" -elfbackup=$userAppBinary"/BFU_"$execname".elf" - -nonce=$SecureEngine"/../Binary/nonce.bin" -magic="SFU"$4 -oemkey=$SecureEngine"/../Binary/OEM_KEY_COMPANY"$4"_key_AES_GCM.bin" -current_directory=`pwd` -cd $SecureEngine"/../../" -SecureDir=`pwd` -cd $current_directory -sbsfuelf="$SecureDir/1_Image_BFU/STM32CubeIDE/Debug/BFU.elf" - -current_directory=`pwd` -cd $1/../../../../../../Middlewares/ST/STM32_Secure_Engine/Utilities/KeysAndImages -basedir=`pwd` -cd $current_directory -# test if window executable usable -prepareimage=$basedir"/win/prepareimage/prepareimage.exe" -uname | grep -i -e windows -e mingw >/dev/null > /dev/null 2>&1 -if [ $? -eq 0 ] && [ -e "$prepareimage" ]; then - echo "prepareimage with windows executable" - export PATH=$basedir"\win\prepareimage";$PATH > /dev/null 2>&1 - cmd="" - prepareimage="prepareimage.exe" -else - # line for python - echo "prepareimage with python script" - prepareimage=$basedir/prepareimage.py - cmd="python" -fi - -# Make sure we have a Binary sub-folder in UserApp folder -if [ ! -e $userAppBinary ]; then -mkdir $userAppBinary -fi - -command=$cmd" "$prepareimage" enc -k "$oemkey" -n "$nonce" "$bin" "$sfu -$command > $projectdir"/output.txt" -ret=$? -if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" sign -k "$oemkey" -n "$nonce" "$bin" "$sign - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" pack -m "$magic" -k "$oemkey" -r 112 -v "$version" -n "$nonce" -f "$sfu" -t "$sign" "$sfb" -o 512" - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" header -m "$magic" -k "$oemkey" -r 112 -v "$version" -n "$nonce" -f "$sfu" -t "$sign" -o 512 "$headerbin - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" merge -v 0 -e 1 -i "$headerbin" -s "$sbsfuelf" -u "$elf" "$bigbinary - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ] && [ $# = 6 ]; then - echo "Generating the global elf file BFU and userApp" - echo "Generating the global elf file BFU and userApp" >> $projectdir"/output.txt" - uname | grep -i -e windows -e mingw > /dev/null 2>&1 - if [ $? -eq 0 ]; then - # Set to the default installation path of the Cube Programmer tool - # If you installed it in another location, please update PATH. - PATH="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin":$PATH > /dev/null 2>&1 - programmertool="STM32_Programmer_CLI.exe" - else - which STM32_Programmer_CLI > /dev/null - if [ $? = 0 ]; then - programmertool="STM32_Programmer_CLI" - else - echo "fix access path to STM32_Programmer_CLI" - fi - fi - command=$programmertool" -ms "$elf" "$headerbin" "$sbsfuelf - $command >> $projectdir"/output.txt" - ret=$? - fi - fi - fi - fi -fi - - -if [ $ret -eq 0 ]; then - rm $sign - rm $sfu - rm $headerbin - exit 0 -else - echo "$command : failed" >> $projectdir"/output.txt" - if [ -e "$elf" ]; then - rm $elf - fi - if [ -e "$elfbackup" ]; then - rm $elfbackup - fi - echo $command : failed - read -n 1 -s - exit 1 -fi diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.sh b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.sh deleted file mode 100644 index 21ba5a75..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/bash - -#Post build for SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 -# arg1 is the build directory -# arg2 is the elf file path+name -# arg3 is the bin file path+name -# arg4 is the firmware Id (1/2/3) -# arg5 is the version -# arg6 when present forces "bigelf" generation -projectdir=$1 -FileName=${3##*/} -execname=${FileName%.*} -elf=$2 -bin=$3 -version=$5 - -SecureEngine=${0%/*} - -userAppBinary=$projectdir"/../Binary" - -sfb=$userAppBinary"/"$execname".sfb" -sign=$userAppBinary"/"$execname".sign" -headerbin=$userAppBinary"/"$execname"sfuh.bin" -bigbinary=$userAppBinary"/BFU_"$execname".bin" -magic="SFU"$4 -ecckey=$SecureEngine"/../Binary/ECCKEY"$4".txt" -current_directory=`pwd` -cd $SecureEngine"/../../" -SecureDir=`pwd` -cd $current_directory -sbsfuelf="$SecureDir/1_Image_BFU/STM32CubeIDE/Debug/BFU.elf" - -current_directory=`pwd` -cd $1/../../../../../../Middlewares/ST/STM32_Secure_Engine/Utilities/KeysAndImages -basedir=`pwd` -cd $current_directory -# test if window executable usable -prepareimage=$basedir"/win/prepareimage/prepareimage.exe" -uname | grep -i -e windows -e mingw > /dev/null 2>&1 -if [ $? -eq 0 ] && [ -e "$prepareimage" ]; then - echo "prepareimage with windows executable" - export PATH=$basedir"\win\prepareimage";$PATH > /dev/null 2>&1 - cmd="" - prepareimage="prepareimage.exe" -else - # line for python - echo "prepareimage with python script" - prepareimage=$basedir/prepareimage.py - cmd="python" -fi - -echo "$cmd $prepareimage" >> $1/output.txt -# Make sure we have a Binary sub-folder in UserApp folder -if [ ! -e $userAppBinary ]; then -mkdir $userAppBinary -fi - - - -command=$cmd" "$prepareimage" sha256 "$bin" "$sign -$command >> $projectdir"/output.txt" -ret=$? -if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" pack -m "$magic" -k "$ecckey" -p 1 -r 44 -v "$version" -f "$bin" -t "$sign" "$sfb" -o 512" - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" header -m "$magic" -k "$ecckey" -p 1 -r 44 -v "$version" -f "$bin" -t "$sign" -o 512 "$headerbin - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" merge -v 0 -e 1 -i "$headerbin" -s "$sbsfuelf" -u "$elf" "$bigbinary - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ] && [ $# = 6 ]; then - echo "Generating the global elf file (BFU and userApp)" - echo "Generating the global elf file (BFU and userApp)" >> $projectdir"/output.txt" - uname | grep -i -e windows -e mingw > /dev/null 2>&1 - if [ $? -eq 0 ]; then - # Set to the default installation path of the Cube Programmer tool - # If you installed it in another location, please update PATH. - PATH="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin":$PATH > /dev/null 2>&1 - programmertool="STM32_Programmer_CLI.exe" - else - which STM32_Programmer_CLI > /dev/null - if [ $? = 0 ]; then - programmertool="STM32_Programmer_CLI" - else - echo "fix access path to STM32_Programmer_CLI" - fi - fi - command=$programmertool" -ms "$elf" "$headerbin" "$sbsfuelf - $command >> $projectdir"/output.txt" - ret=$? - fi - fi - fi -fi - -if [ $ret -eq 0 ]; then - rm $sign - rm $headerbin - exit 0 -else - echo "$command : failed" >> $projectdir"/output.txt" - if [ -e "$elf" ]; then - rm $elf - fi - if [ -e "$elfbackup" ]; then - rm $elfbackup - fi - echo $command : failed - read -n 1 -s - exit 1 -fi diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.sh b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.sh deleted file mode 100644 index aa0b9928..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/bash - -#Post build for SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 -# arg1 is the build directory -# arg2 is the elf file path+name -# arg3 is the bin file path+name -# arg4 is the firmware Id (1/2/3) -# arg5 is the version -# arg6 when present forces "bigelf" generation -projectdir=$1 -FileName=${3##*/} -execname=${FileName%.*} -elf=$2 -bin=$3 -version=$5 - -SecureEngine=${0%/*} - -userAppBinary=$projectdir"/../Binary" - -sfu=$userAppBinary"/"$execname".sfu" -sfb=$userAppBinary"/"$execname".sfb" -sign=$userAppBinary"/"$execname".sign" -headerbin=$userAppBinary"/"$execname"sfuh.bin" -bigbinary=$userAppBinary"/BFU_"$execname".bin" - -iv=$SecureEngine"/../Binary/iv.bin" -magic="SFU"$4 -oemkey=$SecureEngine"/../Binary/OEM_KEY_COMPANY"$4"_key_AES_CBC.bin" -ecckey=$SecureEngine"/../Binary/ECCKEY"$4".txt" -current_directory=`pwd` -cd $SecureEngine"/../../" -SecureDir=`pwd` -cd $current_directory -sbsfuelf="$SecureDir/1_Image_BFU/STM32CubeIDE/Debug/BFU.elf" - -current_directory=`pwd` -cd $1/../../../../../../Middlewares/ST/STM32_Secure_Engine/Utilities/KeysAndImages -basedir=`pwd` -cd $current_directory -# test if window executable usable -prepareimage=$basedir"/win/prepareimage/prepareimage.exe" -uname | grep -i -e windows -e mingw > /dev/null 2>&1 - -if [ $? -eq 0 ] && [ -e "$prepareimage" ]; then - echo "prepareimage with windows executable" - export PATH=$basedir"\win\prepareimage";$PATH > /dev/null 2>&1 - cmd="" - prepareimage="prepareimage.exe" -else - # line for python - echo "prepareimage with python script" - prepareimage=$basedir/prepareimage.py - cmd="python" -fi - -echo "$cmd $prepareimage" >> $1/output.txt -# Make sure we have a Binary sub-folder in UserApp folder -if [ ! -e $userAppBinary ]; then -mkdir $userAppBinary -fi - - -command=$cmd" "$prepareimage" enc -k "$oemkey" -i "$iv" "$bin" "$sfu -$command > "$projectdir"/output.txt -ret=$? -if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" sha256 "$bin" "$sign - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" pack -m "$magic" -k "$ecckey" -r 28 -v "$version" -i "$iv" -f "$sfu" -t "$sign" "$sfb" -o 512" - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" header -m "$magic" -k "$ecckey" -r 28 -v "$version" -i "$iv" -f "$sfu" -t "$sign" -o 512 "$headerbin - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ]; then - command=$cmd" "$prepareimage" merge -v 0 -e 1 -i "$headerbin" -s "$sbsfuelf" -u "$elf" "$bigbinary - $command >> $projectdir"/output.txt" - ret=$? - if [ $ret -eq 0 ] && [ $# = 6 ]; then - echo "Generating the global elf file BFU and userApp" - echo "Generating the global elf file BFU and userApp" >> $projectdir"/output.txt" - uname | grep -i -e windows -e mingw > /dev/null 2>&1 - if [ $? -eq 0 ]; then - # Set to the default installation path of the Cube Programmer tool - # If you installed it in another location, please update PATH. - PATH="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin":$PATH > /dev/null 2>&1 - programmertool="STM32_Programmer_CLI.exe" - else - which STM32_Programmer_CLI > /dev/null - if [ $? = 0 ]; then - programmertool="STM32_Programmer_CLI" - else - echo "fix access path to STM32_Programmer_CLI" - fi - fi - command=$programmertool" -ms "$elf" "$headerbin" "$sbsfuelf - $command >> $projectdir"/output.txt" - ret=$? - fi - fi - fi - fi -fi - -if [ $ret -eq 0 ]; then - rm $sign - rm $sfu - rm $headerbin - exit 0 -else - echo "$command : failed" >> $projectdir"/output.txt" - if [ -e "$elf" ]; then - rm $elf - fi - if [ -e "$elfbackup" ]; then - rm $elfbackup - fi - echo $command : failed - read -n 1 -s - exit 1 -fi diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld deleted file mode 100644 index abd290a8..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld +++ /dev/null @@ -1,156 +0,0 @@ -/* -** LinkerScript -*/ - -/* Entry Point */ -ENTRY(SE_CallGate) - -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0; /* specific stack provided inside secured area */ - -INCLUDE mapping_fwimg.ld -INCLUDE mapping_sbsfu.ld - -/* Define output sections */ -SECTIONS -{ - .SE_CallGate_Code : { KEEP(*(.SE_CallGate_Code)) } > SE_CallGate_ROM_region - - .SE_embedded_Keys : { KEEP(*(.SE_embedded_Keys)) } > SE_Key_region_ROM - - .SE_Startup_Code : { KEEP ( *se_startup.o (.text .text*)) } > SE_Startup_ROM_region - .text : - { - . = ALIGN(8); - *(.text) /* .text sections (code) */ - *(.text*) /* .text* sections (code) */ - *(.glue_7) /* glue arm to thumb code */ - *(.glue_7t) /* glue thumb to arm code */ - *(.eh_frame) - - KEEP (*(.init)) - KEEP (*(.fini)) - - . = ALIGN(8); - _etext = .; /* define a global symbols at end of code */ - } >SE_Code_NoKey_ROM_region - - /* Constant data goes into FLASH */ - .rodata : - { - . = ALIGN(8); - *(.rodata) /* .rodata sections (constants, strings, etc.) */ - *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ - . = ALIGN(8); - } >SE_Code_NoKey_ROM_region - - .ARM.extab : - { - . = ALIGN(8); - *(.ARM.extab* .gnu.linkonce.armextab.*) - . = ALIGN(8); - } >SE_Code_NoKey_ROM_region - - .ARM : { - . = ALIGN(8); - __exidx_start = .; - *(.ARM.exidx*) - __exidx_end = .; - . = ALIGN(8); - } >SE_Code_NoKey_ROM_region - - .preinit_array : - { - . = ALIGN(8); - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array*)) - PROVIDE_HIDDEN (__preinit_array_end = .); - . = ALIGN(8); - } >SE_Code_NoKey_ROM_region - - .init_array : - { - . = ALIGN(8); - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array*)) - PROVIDE_HIDDEN (__init_array_end = .); - . = ALIGN(8); - } >SE_Code_NoKey_ROM_region - - .fini_array : - { - . = ALIGN(8); - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT(.fini_array.*))) - KEEP (*(.fini_array*)) - PROVIDE_HIDDEN (__fini_array_end = .); - . = ALIGN(8); - } >SE_Code_NoKey_ROM_region - - /* used by the startup to initialize data */ - _sidata = LOADADDR(.data); - - /* Initialized data sections goes into RAM, load LMA copy after code */ - .data : - { - . = ALIGN(8); - _sdata = .; /* create a global symbol at data start */ - *(.data) /* .data sections */ - *(.data*) /* .data* sections */ - - . = ALIGN(8); - _edata = .; /* define a global symbol at data end */ - } >SE_RAM_region AT>SE_Code_NoKey_ROM_region - - - /* Uninitialized data section */ - . = ALIGN(8); - .bss : - { - /* This is used by the startup in order to initialize the .bss section */ - _sbss = .; /* define a global symbol at bss start */ - __bss_start__ = _sbss; - *(.bss) - *(.bss*) - *(COMMON) - - . = ALIGN(8); - _ebss = .; /* define a global symbol at bss end */ - __bss_end__ = _ebss; - } >SE_RAM_region - - BOOTINFO_DATA : - { - . = ALIGN(8); - _sBOOTINFO_DATA = .; /* create a global symbol at BOOTINFO_DATA start */ - *(BOOTINFO_DATA) /* BOOTINFO_DATA* sections */ - *(BOOTINFO_DATA*) - . = ALIGN(8); - _eBOOTINFO_DATA = .; /* define a global symbol at BOOTINFO_DATA end */ - - } >SE_RAM_region AT> SE_Code_NoKey_ROM_region - - /* User_heap_stack section, used to check that there is enough "SRAM1" Ram type memory left */ - ._user_heap_stack : - { - . = ALIGN(8); - PROVIDE ( end = . ); - PROVIDE ( _end = . ); - . = . + _Min_Heap_Size; - . = . + _Min_Stack_Size; - . = ALIGN(8); - } >SE_RAM_region - - /* Remove information from the standard libraries */ - /DISCARD/ : - { - libc.a ( * ) - libm.a ( * ) - libgcc.a ( * ) - } - - .ARM.attributes 0 : { *(.ARM.attributes) } -} - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/prebuild.sh b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/prebuild.sh deleted file mode 100644 index 7358087d..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/prebuild.sh +++ /dev/null @@ -1,205 +0,0 @@ -#!/bin/bash - -#prebuild script -echo prebuild.sh : started > $1/output.txt -asmfile=$1/se_key.s -# comment this line to force python -# python is used if executable not found -current_directory=`pwd` -cd $1/../../../../../../Middlewares/ST/STM32_Secure_Engine/Utilities/KeysAndImages -basedir=`pwd` -cd $current_directory -SBSFUBootLoader=$1/../.. - -# test if window executable usable -prepareimage=$basedir/win/prepareimage/prepareimage.exe -uname | grep -i -e windows -e mingw > /dev/null 2>&1 - -if [ $? -eq 0 ] && [ -e "$prepareimage" ]; then - echo "prepareimage with windows executable" >> $1/output.txt - echo "prepareimage with windows executable" - cmd="" -else - # line for python - echo "prepareimage with python script" >> $1/output.txt - echo "prepareimage with python script" - prepareimage=$basedir/prepareimage.py - cmd=python -fi - -echo "$cmd $prepareimage" >> $1/output.txt -crypto_h=$1/../Inc/se_crypto_config.h - -#clean -if [ -e "$1/crypto.txt" ]; then - rm $1"/crypto.txt" -fi - -if [ -e "$asmfile" ]; then - rm $asmfile -fi - -if [ -e "$1"/postbuild.sh ]; then - rm $1"/postbuild.sh" -fi - -#get crypto name -command="$cmd $prepareimage conf "$crypto_h"" -echo $command -crypto=`$command` -echo $crypto > $1"/crypto.txt" -echo "$crypto selected">> $1"/output.txt" -echo $crypto selected -ret=$? - -kms_config=$1"/kms_platf_objects_config.h" -kms_tmp=$1"/kms_platf_objects_config.h.tmp" - -#Patch KMS embedded keys with Blob Keys -if [ $ret -eq 0 ]; then - kms_blob_ecckey=$SBSFUBootLoader"/1_Image_KMS_Blob/Binary/ECCKEY.txt" - command=$cmd" "$prepareimage" inject -k "$kms_blob_ecckey" -f "$1"/../Inc/kms_platf_objects_config.h.pattern -p @ECDSA_BLOB_KEY@ "$kms_tmp - echo $command - $command - ret=$? - if [ $ret -eq 0 ]; then - kms_blob_oemkey=$SBSFUBootLoader"/1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin" - command=$cmd" "$prepareimage" inject -k "$kms_blob_oemkey" -f "$kms_tmp" -p @AES_BLOB_KEY@ "$kms_config - echo $command - $command - ret=$? - fi -fi - -# Patch AES keys part -if [ $ret -eq 0 ]; then - type="vide" - if [ $crypto = "SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM" ]; then - type="GCM" - fi - if [ $crypto = "SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256" ]; then - type="CBC" - fi - if [ $crypto = "SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256" ]; then -# For KMS dummy AES keys are needed (reusing AES_CBC inputs files) - type="CBC" - fi - if [ $type != "vide" ]; then - oemkey="$1/../Binary/OEM_KEY_COMPANY1_key_AES_$type.bin" - command="cat "$kms_config - $command > $kms_tmp - ret=$? - if [ $? -eq 0 ]; then - command=$cmd" "$prepareimage" inject -k "$oemkey" -f "$kms_tmp" -p @AES_SBSFU_KEY_1@ "$kms_config - echo $command - $command - ret=$? - fi - - oemkey="$1/../Binary/OEM_KEY_COMPANY2_key_AES_$type.bin" - if [ -e "$oemkey" ]; then - command="cat "$kms_config - $command > $kms_tmp - ret=$? - if [ $? -eq 0 ]; then - command=$cmd" "$prepareimage" inject -k "$oemkey" -f "$kms_tmp" -p @AES_SBSFU_KEY_2@ "$kms_config - echo $command - $command - ret=$? - fi - fi - - oemkey="$1/../Binary/OEM_KEY_COMPANY3_key_AES_$type.bin" - if [ -e "$oemkey" ]; then - command="cat "$kms_config - $command > $kms_tmp - ret=$? - if [ $? -eq 0 ]; then - command=$cmd" "$prepareimage" inject -k "$oemkey" -f "$kms_tmp" -p @AES_SBSFU_KEY_3@ "$kms_config - echo $command - $command - ret=$? - fi - fi - fi -fi - -# Patch ECC keys part -if [ $ret -eq 0 ]; then - type="vide" - if [ $crypto = "SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256" ]; then - type="ECC" - fi - if [ $crypto = "SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256" ]; then - type="ECC" - fi - if [ $crypto = "SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM" ]; then -# For KMS dummy ECC keys are needed - type="ECC" - fi - if [ $type != "vide" ]; then - ecckey="$1/../Binary/ECCKEY1.txt" - command="cat "$kms_config - $command > $kms_tmp - ret=$? - if [ $? -eq 0 ]; then - command=$cmd" "$prepareimage" inject -k "$ecckey" -f "$kms_tmp" -p @ECDSA_SBSFU_KEY_1@ "$kms_config - echo $command - $command - ret=$? - fi - - ecckey="$1/../Binary/ECCKEY2.txt" - if [ -e "$ecckey" ]; then - command="cat "$kms_config - $command > $kms_tmp - ret=$? - if [ $? -eq 0 ]; then - command=$cmd" "$prepareimage" inject -k "$ecckey" -f "$kms_tmp" -p @ECDSA_SBSFU_KEY_2@ "$kms_config - echo $command - $command - ret=$? - fi - fi - - ecckey="$1/../Binary/ECCKEY3.txt" - if [ -e "$ecckey" ]; then - command="cat "$kms_config - $command > $kms_tmp - ret=$? - if [ $? -eq 0 ]; then - command=$cmd" "$prepareimage" inject -k "$ecckey" -f "$kms_tmp" -p @ECDSA_SBSFU_KEY_3@ "$kms_config - echo $command - $command - ret=$? - fi - fi - fi -fi - -rm $kms_tmp - -if [ $ret -eq 0 ]; then -#no error recopy post build script - uname | grep -i -e windows -e mingw > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "recopy postbuild.sh script with "$crypto".sh script" - command="cat "$1"/"$crypto".sh" - $command > "$1"/"postbuild.sh" - ret=$? - else - echo "create symbolic link postbuild.sh to "$crypto".sh" - command="ln -s ./"$crypto".sh "$1"/postbuild.sh" - $command - ret=$? - fi -fi - -if [ $ret != 0 ]; then -#an error -echo $command : failed >> $1/output.txt -echo $command : failed -read -n 1 -s -exit 1 -fi -exit 0 - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/ca_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/ca_low_level.c deleted file mode 100644 index f641765f..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/ca_low_level.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - ****************************************************************************** - * @file ca_low_level.c - * @author MCD Application Team - * @brief This file contains the low level implementations of the Cryptographic API (CA) module. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef CA_LOW_LEVEL_C -#define CA_LOW_LEVEL_C - -/* Includes ------------------------------------------------------------------*/ -#include "CryptoApi/ca.h" - -/* Private defines -----------------------------------------------------------*/ -/* Private typedef -----------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ - - -/* Exported functions implementation -----------------------------------------*/ - -#if defined(CA_HAL_CRYPTOLIB_SUPP) - -#if ((CA_ROUTE_AES_CBC & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ - || ((CA_ROUTE_AES_CCM & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ - || ((CA_ROUTE_AES_CMAC & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ - || ((CA_ROUTE_AES_ECB & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ - || ((CA_ROUTE_AES_GCM & CA_ROUTE_MASK) == CA_ROUTE_HAL) - -/** - * @brief CRYP MSP Initialization - * This function configures the hardware resources - * @param hcryp: CRYP handle pointer - * @retval None - */ -void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp) -{ - if (hcryp->Instance == CA_AES_INSTANCE) - { - /* Release AES/CRYP from reset state */ - __HAL_RCC_AES_RELEASE_RESET(); - /* Peripheral clock enable */ - __HAL_RCC_AES_CLK_ENABLE(); - } -} - -/** - * @brief CRYP MSP De-Initialization - * This function freeze the hardware resources - * @param hcryp: CRYP handle pointer - * @retval None - */ -void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp) -{ - if (hcryp->Instance == CA_AES_INSTANCE) - { - /* Peripheral clock disable */ - __HAL_RCC_AES_CLK_DISABLE(); - /* Force AES/CRYP into reset state */ - __HAL_RCC_AES_FORCE_RESET(); - } -} -#endif /* CA_ROUTE_AES_CBC || CA_ROUTE_AES_CCM || CA_ROUTE_AES_CMAC \ - || CA_ROUTE_AES_ECB || CA_ROUTE_AES_GCM => CA_ROUTE_HAL */ - - -#if ((CA_ROUTE_ECC_ECDSA & CA_ROUTE_MASK) == CA_ROUTE_HAL) || ((CA_ROUTE_RSA & CA_ROUTE_MASK) == CA_ROUTE_HAL) -/** - * @brief PKA MSP Initialization - * This function configures the hardware resources used in this example - * @param[in] hpka: PKA handle pointer - * @retval None - */ -void HAL_PKA_MspInit(PKA_HandleTypeDef *hpka) -{ - if (hpka->Instance == CA_PKA_INSTANCE) - { - /* Release PKA from reset state */ - __HAL_RCC_PKA_RELEASE_RESET(); - /* Peripheral clock enable */ - __HAL_RCC_PKA_CLK_ENABLE(); - } -} - -/** - * @brief PKA MSP De-Initialization - * This function freeze the hardware resources used in this example - * @param[in] hpka: PKA handle pointer - * @retval None - */ -void HAL_PKA_MspDeInit(PKA_HandleTypeDef *hpka) -{ - if (hpka->Instance == CA_PKA_INSTANCE) - { - /* Peripheral clock disable */ - __HAL_RCC_PKA_CLK_DISABLE(); - /* Force PKA into reset state */ - __HAL_RCC_PKA_FORCE_RESET(); - } -} -#endif /* CA_ROUTE_ECC_ECDSA || CA_ROUTE_RSA => CA_ROUTE_HAL */ - -#endif /* CA_HAL_CRYPTOLIB_SUPP */ - - -#if defined(CA_ST_CRYPTOLIB_SUPP) -/** - * @brief CRC initialization - * This function release reset and clock CRC IP peripheral - * @retval None - */ -void CA_LL_CRC_Init(void) -{ - /* Force CRC into reset state */ - __HAL_RCC_CRC_FORCE_RESET(); - /* Release CRC from reset state */ - __HAL_RCC_CRC_RELEASE_RESET(); - /* Peripheral clock enable */ - __HAL_RCC_CRC_CLK_ENABLE(); -} - -#endif /* CA_ST_CRYPTOLIB_SUPP */ - -#endif /* CA_LOW_LEVEL_C */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/se_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/se_low_level.c deleted file mode 100644 index e69e2547..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/se_low_level.c +++ /dev/null @@ -1,642 +0,0 @@ -/** - ****************************************************************************** - * @file se_low_level.c - * @author MCD Application Team - * @brief Secure Engine Interface module. - * This file provides set of firmware functions to manage SE low level - * interface functionalities. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#define SE_LOW_LEVEL_C - -/* Includes ------------------------------------------------------------------*/ -#include "se_low_level.h" -#if defined(__ARMCC_VERSION) -#include "mapping_sbsfu.h" -#endif /* __CC_ARM */ -#include "se_exception.h" -#include "string.h" - -/** @addtogroup SE Secure Engine - * @{ - */ -/** @defgroup SE_HARDWARE SE Hardware Interface - * @{ - */ - -/** @defgroup SE_HARDWARE_Private_Variables Private Variables - * @{ - */ -static CRC_HandleTypeDef CrcHandle; /*!< SE Crc Handle*/ - -static __IO uint32_t SE_DoubleECC_Error_Counter = 0U; - -/** - * @} - */ - -/** @defgroup SE_HARDWARE_Private_Functions Private Functions - * @{ - */ - -static uint32_t SE_LL_GetPage(uint32_t Address); -/** - * @} - */ - -/** @defgroup SE_HARDWARE_Exported_Variables Exported Variables - * @{ - */ - -/** - * @} - */ - -/** @defgroup SE_HARDWARE_Exported_Functions Exported Functions - * @{ - */ - -/** @defgroup SE_HARDWARE_Exported_CRC_Functions CRC Exported Functions - * @{ - */ - -/** - * @brief Set CRC configuration and call HAL CRC initialization function. - * @param None. - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise - */ -SE_ErrorStatus SE_LL_CRC_Config(void) -{ - SE_ErrorStatus e_ret_status = SE_ERROR; - - CrcHandle.Instance = CRC; - /* The input data are not inverted */ - CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; - - /* The output data are not inverted */ - CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; - - /* The Default polynomial is used */ - CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; - /* The default init value is used */ - CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; - /* The input data are 32-bit long words */ - CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS; - /* CRC Init*/ - if (HAL_CRC_Init(&CrcHandle) == HAL_OK) - { - e_ret_status = SE_SUCCESS; - } - - return e_ret_status; -} - -/** - * @brief Wrapper to HAL CRC initialization function. - * @param None - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_CRC_Init(void) -{ - /* CRC Peripheral clock enable */ - __HAL_RCC_CRC_CLK_ENABLE(); - - return SE_LL_CRC_Config(); -} - -/** - * @brief Wrapper to HAL CRC de-initialization function. - * @param None - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_CRC_DeInit(void) -{ - SE_ErrorStatus e_ret_status = SE_ERROR; - - if (HAL_CRC_DeInit(&CrcHandle) == HAL_OK) - { - /* Initialization OK */ - e_ret_status = SE_SUCCESS; - } - - return e_ret_status; -} - -/** - * @brief Wrapper to HAL CRC Calculate function. - * @param pBuffer: pointer to data buffer. - * @param uBufferLength: buffer length in 32-bits word. - * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) - */ -uint32_t SE_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t uBufferLength) -{ - return HAL_CRC_Calculate(&CrcHandle, pBuffer, uBufferLength); -} - -/** - * @} - */ - -/** @defgroup SE_HARDWARE_Exported_FLASH_Functions FLASH Exported Functions - * @{ - */ - -/** - * @brief This function does an erase of nb pages in user flash area - * @param pStart: pointer to user flash area - * @param Length: number of bytes. - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_FLASH_Erase(uint8_t *pStart, uint32_t Length) -{ - uint32_t page_error = 0U; - uint32_t start = (uint32_t)pStart; - FLASH_EraseInitTypeDef p_erase_init; - SE_ErrorStatus e_ret_status = SE_SUCCESS; - - /* Unlock the Flash to enable the flash control register access *************/ - if (HAL_FLASH_Unlock() == HAL_OK) - { - /* Fill EraseInit structure*/ - p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; - p_erase_init.Page = SE_LL_GetPage(start); - p_erase_init.NbPages = SE_LL_GetPage(start + Length - 1U) - p_erase_init.Page + 1U; - if (HAL_FLASHEx_Erase(&p_erase_init, &page_error) != HAL_OK) - { - e_ret_status = SE_ERROR; - } - - /* Lock the Flash to disable the flash control register access (recommended - to protect the FLASH memory against possible unwanted operation) *********/ - (void)HAL_FLASH_Lock(); - } - else - { - e_ret_status = SE_ERROR; - } - - return e_ret_status; -} - -/** - * @brief Write in Flash protected area - * @param pDestination pointer to destination area in Flash - * @param pSource pointer to input buffer - * @param Length number of bytes to be written - * @retval SE_SUCCESS if successful, otherwise SE_ERROR - */ - -SE_ErrorStatus SE_LL_FLASH_Write(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) -{ - SE_ErrorStatus ret = SE_SUCCESS; - uint32_t i; - uint32_t verified = 0U; - uint32_t destination = (uint32_t)pDestination; - uint32_t source = (uint32_t)pSource; - - if (Length == 0U) - { - return SE_ERROR; - } - - /* Area should be inside 1 of the firmware image headers */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - if ((destination >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && - ((destination + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) - { - verified = 1U; - } - } - if (verified == 0U) - { - return SE_ERROR; - } - - /* Unlock the Flash to enable the flash control register access *************/ - if (HAL_FLASH_Unlock() == HAL_OK) - { - for (i = 0U; i < Length; i += 8U) - { - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (destination + i), *(uint64_t *)(source + i)) != HAL_OK) - { - ret = SE_ERROR; - break; - } - } - - /* Lock the Flash to disable the flash control register access (recommended - to protect the FLASH memory against possible unwanted operation) */ - (void)HAL_FLASH_Lock(); - } - else - { - ret = SE_ERROR; - } - return ret; -} - -/** - * @brief Read in Flash protected area - * @param pDestination: Start address for target location - * @param pSource: pointer on buffer with data to read - * @param Length: Length in bytes of data buffer - * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) -{ - uint32_t source = (uint32_t)pSource; - SE_ErrorStatus e_ret_status = SE_ERROR; - uint32_t i; - uint32_t verified = 0U; - - - /* Area should be inside 1 of the firmware image headers - or inside 1 of the download areas */ - for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) - { - if ((source >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && - ((source + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) - { - verified = 1U; - } - } - - for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) - { - if ((source >= SlotStartAdd[SLOT_DWL_1 + i]) && - ((source + Length) <= (SlotStartAdd[SLOT_DWL_1 + i] + SLOT_SIZE(SLOT_DWL_1)))) - { - verified = 1U; - } - } - - if (verified == 0U) - { - return SE_ERROR; - } - - SE_DoubleECC_Error_Counter = 0U; - (void)memcpy(pDestination, pSource, Length); - if (SE_DoubleECC_Error_Counter == 0U) - { - e_ret_status = SE_SUCCESS; - } - SE_DoubleECC_Error_Counter = 0U; - return e_ret_status; -} - -/** - * @} - */ - -/** @defgroup SE_HARDWARE_Exported_FLASH_EXT_Functions External FLASH Exported Functions - * @{ - */ - -/** - * @brief Initialization of external flash On The Fly DECryption (OTFDEC) - * @param pxSE_Metadata: Firmware metadata. - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_FLASH_EXT_Decrypt_Init(SE_FwRawHeaderTypeDef *pxSE_Metadata) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(pxSE_Metadata); - return SE_SUCCESS; -} - -/** - * @} - */ - -/** - * @brief Check if an array is inside the RAM of the product - * @param Addr : address of array - * @param Length : length of array in byte - */ -SE_ErrorStatus SE_LL_Buffer_in_ram(void *pBuff, uint32_t Length) -{ - SE_ErrorStatus e_ret_status; - uint32_t addr_start = (uint32_t)pBuff; - uint32_t addr_end = addr_start + Length - 1U; - - /* Check if length is positive with no overflow */ - if ((Length != 0U) && (!((0xFFFFFFFFUL - addr_start) < Length)) - && ((addr_end <= SB_REGION_RAM_END) && (addr_start >= (SE_REGION_RAM_END + 1U)))) - { - e_ret_status = SE_SUCCESS; - } - else - { - e_ret_status = SE_ERROR; - - /* Could be an attack ==> Reset */ - NVIC_SystemReset(); - } - return e_ret_status; -} - -/** - * @brief function checking if a buffer is in sbsfu ram. - * @param pBuff: address of buffer - * @param Length: length of buffer in bytes - * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_Buffer_in_SBSFU_ram(const void *pBuff, uint32_t Length) -{ - SE_ErrorStatus e_ret_status; - uint32_t addr_start = (uint32_t)pBuff; - uint32_t addr_end = addr_start + Length - 1U; - - /* Check if length is positive with no overflow */ - if ((Length != 0U) && (!((0xFFFFFFFFUL - addr_start) < Length)) - && ((addr_end <= SB_REGION_RAM_END) && (addr_start >= SB_REGION_RAM_START))) - { - e_ret_status = SE_SUCCESS; - } - else - { - e_ret_status = SE_ERROR; - - /* Could be an attack ==> Reset */ - NVIC_SystemReset(); - } - return e_ret_status; -} - -/** - * @brief function checking if a buffer is PARTLY in se ram. - * @param pBuff: address of buffer - * @param Length: length of buffer in bytes - * @retval SE_ErrorStatus SE_SUCCESS for buffer in NOT se ram, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_Buffer_part_of_SE_ram(const void *pBuff, uint32_t Length) -{ - SE_ErrorStatus e_ret_status; - uint32_t addr_start = (uint32_t)pBuff; - uint32_t addr_end = addr_start + Length - 1U; - - /* Check if length is positive with no overflow */ - if (((Length != 0U) && (!(((addr_start < SE_REGION_RAM_START) && (addr_end < SE_REGION_RAM_START)) || - ((addr_start > SE_REGION_RAM_END) && (addr_end > SE_REGION_RAM_END))))) - || ((0xFFFFFFFFUL - addr_start) < Length)) - { - e_ret_status = SE_SUCCESS; - - /* Could be an attack ==> Reset */ - NVIC_SystemReset(); - } - else - { - e_ret_status = SE_ERROR; - } - return e_ret_status; -} - -/** - * @brief function checking if a buffer is PARTLY in se rom. - * @param pBuff: address of buffer - * @param Length: length of buffer in bytes - * @retval SE_ErrorStatus SE_SUCCESS for buffer in NOT se rom, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_Buffer_part_of_SE_rom(const void *pBuff, uint32_t Length) -{ - SE_ErrorStatus e_ret_status; - uint32_t addr_start = (uint32_t)pBuff; - uint32_t addr_end = addr_start + Length - 1U; - - /* Check if length is positive with no overflow */ - if (((Length != 0U) && (!(((addr_start < SE_CODE_REGION_ROM_START) && (addr_end < SE_CODE_REGION_ROM_START)) - || ((addr_start > SE_CODE_REGION_ROM_END) && (addr_end > SE_CODE_REGION_ROM_END)) - ))) - || ((0xFFFFFFFFUL - addr_start) < Length)) - { - e_ret_status = SE_SUCCESS; - - /* Could be an attack ==> Reset */ - NVIC_SystemReset(); - } - else - { - e_ret_status = SE_ERROR; - } - return e_ret_status; -} - -/** - * @} - */ - -/** @addtogroup SE_BUFFER_CHECK_Exported_RAM_Functions - * @{ - */ - -/** - * @brief function to disable all IRQ, previously enabled ones are stored in parameter - * @param pIrqState: IRQ state buffer - * @param IrqStateNb: Number of IRQ state that can be stored - * @retval SE_ErrorStatus SE_SUCCESS when complete successfully, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_Save_Disable_Irq(uint32_t *pIrqState, uint32_t IrqStateNb) -{ - SE_ErrorStatus e_ret_status = SE_ERROR; - return e_ret_status; -} - -/** - * @brief function checking if a buffer is PARTLY in se rom. - * @param pBuff: address of buffer - * @param Length: length of buffer in bytes - * @retval SE_ErrorStatus SE_SUCCESS for buffer in NOT se rom, SE_ERROR otherwise. - */ -SE_ErrorStatus SE_LL_Restore_Enable_Irq(uint32_t *pIrqState, uint32_t IrqStateNb) -{ - SE_ErrorStatus e_ret_status = SE_ERROR; - return e_ret_status; -} - -/** - * @} - */ - -/** - * @} - */ - -/** @addtogroup SE_HARDWARE_Private_Functions - * @{ - */ - -/** - * @brief Gets the page of a given address - * @param Addr: Address of the FLASH Memory - * @retval The page of a given address - */ -static uint32_t SE_LL_GetPage(uint32_t Address) -{ - uint32_t page; - - if (Address < (FLASH_BASE + (FLASH_BANK_SIZE))) - { - /* Bank 1 */ - page = (Address - FLASH_BASE) / FLASH_PAGE_SIZE; - } - else - { - /* Bank 2 */ - page = (Address - (FLASH_BASE + (FLASH_BANK_SIZE))) / FLASH_PAGE_SIZE; - } - return page; -} - -/** - * @brief Gets the bank of a given address - * @param Addr: Address of the FLASH Memory - * @retval The bank of a given address - */ - - -/** - * @brief Get Link Register value (LR) - * @param None. - * @retval LR Register value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_LR(void) -{ - register uint32_t result; - -#if defined ( __ICCARM__ ) || ( __GNUC__ ) - __ASM volatile("MOV %0, LR" : "=r"(result)); -#elif defined ( __CC_ARM ) - __ASM volatile("MOV result, __return_address()"); -#endif /* ( __ICCARM__ ) || ( __GNUC__ ) */ - - return result; -} - -/* - As this handler code relies on stack pointer position to manipulate the PC return value, it is important - not to use extra registers (on top of scratch registers), because it would change the stack pointer - position. Then compiler optimizations are customized to ensure that. -*/ -#if defined(__ICCARM__) -#pragma optimize=none -#elif defined(__CC_ARM) -#pragma O0 -#elif defined(__ARMCC_VERSION) -__attribute__((optnone)) -#elif defined(__GNUC__) -__attribute__((optimize("O1"))) -#endif /* __ICCARM__ */ - -/** - * @brief NMI Handler present for handling Double ECC NMI interrupt - * @param None. - * @retval None. - */ -void NMI_Handler(void) -{ - uint32_t *p_sp; - uint32_t lr; - uint16_t opcode_msb; - - if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)) - { - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); - - /* Memorize error to ignore the read value */ - SE_DoubleECC_Error_Counter++; - - lr = __get_LR(); - - /* Check EXC_RETURN value in LR to know which SP was used prior entering exception */ - if (((lr) & (0xFU)) == 0xDU) - { - /* interrupted code was using Process Stack Pointer */ - p_sp = (uint32_t *)__get_PSP(); - } - else - { - /* interrupted code was using Main Stack Pointer */ - p_sp = (uint32_t *)__get_MSP(); - } - - /* Test caller mode T bit from CPSR in stack */ - if ((*(p_sp + 7U) & (1U << xPSR_T_Pos)) != 0U) - { - /* Thumb mode. - Test PC in stack. - If bits [15:11] of the halfword being decoded take any of the following values, - the halfword is the first halfword of a 32-bit instruction: 0b11101, 0b11110, 0b11111. - Otherwise, the halfword is a 16-bit instruction. - */ - opcode_msb = (*(uint16_t *)(*(p_sp + 6) & 0xFFFFFFFEU) & 0xF800U); - if ((opcode_msb == 0xE800U) || (opcode_msb == 0xF000U) || (opcode_msb == 0xF800U)) - { - /* execute next instruction PC +4 */ - *(p_sp + 6U) += 4U; - } - else - { - /* execute next instruction PC +2 */ - *(p_sp + 6U) += 2U; - } - } - else - { - /* ARM mode execute next instruction PC +4 */ - *(p_sp + 6U) += 4U; - } - } - else - { - /* This exception occurs for another reason than flash double ECC errors */ - SE_NMI_ExceptionHandler(); - } -} - -/** - * @brief Hard Fault Handler present for handling Double ECC Bus Fault interrupt - * @param None. - * @retvat void - */ -void HardFault_Handler(void) -{ - SE_NMI_ExceptionHandler(); -} - -/** - * @brief Cleanup SE CORE - * The function is called during SE_LOCK_RESTRICT_SERVICES. - * - */ -void SE_LL_CORE_Cleanup(void) -{ -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/readme.txt deleted file mode 100644 index 4c742c61..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/readme.txt +++ /dev/null @@ -1,112 +0,0 @@ -/** - @page 1_Image_SECoreBin / Secure Engine Core binary generation. - - @verbatim - ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* - * @file readme.txt - * @brief Secure Engine Core binary generation. - * SE Core binary exports SE CallGate function entry point for - * FU Application. - ****************************************************************************** - * - * Copyright (c) 2017 STMicroelectronics. All rights reserved. - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - @endverbatim - -@par Application Description - -This application is used to generate Secure Engine Core binary file to be linked -with Boot & Firmware Update application (BFU). -SE Core binary exports a single entry point to SE CallGate function and a startup -method for data initialization. It is based on the Secure Engine Middleware. - -Generated SE Core Binary embeds Key Management Services accessible through this same -single entry point using APIs defined by iKMS interface. - -It has to be compiled before BFU project. - -Three cryptographic schemes are provided as example to illustrate the cryptographic operations. The default cryptographic -scheme uses both symmetric (AES-CBC) and asymmetric (ECDSA) cryptography. Two alternate schemes are provided and can be -selected thanks to SECBOOT_CRYPTO_SCHEME compiler switch named : -- SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 (default) -- SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 -- SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM - -For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" -available from the STMicroelectronics microcontroller website www.st.com. - -@par Keywords - -Security, KMS, SBSFU - -@par Directory contents - - - 1_Image_SECoreBin/Src/ca_low_level.c Low level implementations of the Cryptographic API (CA) module - - 1_Image_SECoreBin/Src/kms_low_level.c Key Management Services low level interface - - 1_Image_SECoreBin/Src/nvms_low_level.c Non volatile memory storage low level interface - - 1_Image_SECoreBin/Src/se_low_level.c Low level interface - - 1_Image_SECoreBin/Inc/ca_conf.h Configuration for Cryptographic API (CA) module functionalities - - 1_Image_SECoreBin/Inc/ca_low_level.h Header for ca_low_level.c - - 1_Image_SECoreBin/Inc/kms_config.h Key Management Services configuration file - - 1_Image_SECoreBin/Inc/kms_low_level.h Header for kms_low_level.c - - 1_Image_SECoreBin/Inc/kms_mem_pool_def.h KMS memory pool definition file - - 1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern Header for Key Management Services embedded objects definitions pattern - Appropriate cryptographic scheme keys are injected into it by the prebuild script (see below) - - 1_Image_SECoreBin/Inc/kms_platf_objects_interface.h Header for Key Management Services embedded objects references (labels, IDs...) - Exported to KMS user to ease embedded object usage - - 1_Image_SECoreBin/Inc/mbed_crypto_config.h mbed-crypto configuration file - - 1_Image_SECoreBin/Inc/nvms_low_level.h Header for nvms_low_level.c - - 1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h HAL configuration file - - 1_Image_SECoreBin/Inc/se_crypto_config.h Crypto scheme configuration (crypto scheme used by the bootloader) - - 1_Image_SECoreBin/Inc/se_def_metadata.h Firmware metadata (header) definition - - 1_Image_SECoreBin/Inc/se_low_level.h Header file for low level interface - - 1_Image_SECoreBin/Binary/ECCKEY1.txt Private ECCDSA key for signature verification - - 1_Image_SECoreBin/Binary/ECCKEY2.txt Private ECCDSA key for signature verification of a possible 2nd active image - - 1_Image_SECoreBin/Binary/ECCKEY3.txt Private ECCDSA key for signature verification of a possible 3rd active image - - 1_Image_SECoreBin/Binary/nonce.bin Number used only once for firmware encryption - - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin Public key for AES CBC encryption - - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin Public key for AES GCM encryption - - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY2_key_AES_CBC.bin Public key for AES CBC encryption of a possible 2nd active image - - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY2_key_AES_GCM.bin Public key for AES GCM encryption of a possible 2nd active image - - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY3_key_AES_CBC.bin Public key for AES CBC encryption of a possible 3rd active image - - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY3_key_AES_GCM.bin Public key for AES GCM encryption of a possible 3rd active image - -@par Hardware and Software environment - - - This example runs on STM32WL55xx devices - - This example has been tested with NUCLEO-WL55JC RevC board and can be - easily tailored to any other supported device and development board. - - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware - is a feature provided by STM32Cube programmer available on www.st.com. - - Microsoft Windows has a limitation whereby paths to files and directories cannot - be longer than 256 characters. Paths to files exceeding that limits cause tools (e.g. compilers, - shell scripts) to fail reading from or writing to such files. - As a workaround, it is advised to use the subst.exe command from within a command prompt to set - up a local drive out of an existing directory on the hard drive, such as: - C:\> subst X: \Firmware - - -@par IDE prebuild script - -In order to ease the development process, a prebuild script ("prebuild.bat") is integrated in each IDE project. -This preliminary processing is in charge of: - - determining the requested cryptographic scheme - - generating the appropriate keys in /kms_platf_objects_config.h (from injection of BFU & Blob importation keys into the KMS embedded objects pattern file) - - generating the appropriate script to prepare the firmware image ("postbuild.bat") when building the UserApp project -A known limitation of this integration occurs when you update a cryptographic parameter (for instance the cryptographic key). -The IDE does not track this update so you need to force the rebuild of the project manually. - -@par How to use it ? - -In order to generate Secure Engine Core binary file, you must do the following : - - Open your preferred toolchain - - Rebuild the project - - *

      © COPYRIGHT STMicroelectronics

      - */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/Project.ewp deleted file mode 100644 index 42643233..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/Project.ewp +++ /dev/null @@ -1,1189 +0,0 @@ - - - 2 - - STM32WL55JC_Nucleo_1_Image_UserApp - - ARM - - 1 - - General - 3 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 34 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 10 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - cmd /C "cmd /C $PROJ_DIR$\..\..\1_Image_SECoreBin\EWARM\PostBuild.bat "$PROJ_DIR$" "$TARGET_PATH$" "$PROJ_DIR$\UserApp.bin" 1 1" - - - - ILINK - 0 - - 21 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - - Doc - - $PROJ_DIR$\..\readme.txt - - - - Application - - User - - $PROJ_DIR$\..\Src\main.c - - - $PROJ_DIR$\..\Src\com.c - - - $PROJ_DIR$\..\Src\common.c - - - $PROJ_DIR$\..\Src\fw_update_app.c - - - $PROJ_DIR$\..\Src\se_user_code.c - - - $PROJ_DIR$\..\Src\test_protections.c - - - $PROJ_DIR$\..\Src\ymodem.c - - - $PROJ_DIR$\..\Src\flash_if.c - - - $PROJ_DIR$\..\Src\stm32wlxx_it.c - - - $PROJ_DIR$\..\Src\kms_object_update_app.c - - - $PROJ_DIR$\..\Src\tkms_app.c - - - $PROJ_DIR$\..\Src\tkms_app_derive_key.c - - - $PROJ_DIR$\..\Src\tkms_app_encrypt_decrypt.c - - - $PROJ_DIR$\..\Src\tkms_app_sign_verify.c - - - - EWARM - - $PROJ_DIR$\startup_stm32wl55xx_cm4.s - - - - - Drivers - - BSP - - STM32WLxx_Nucleo - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\BSP\STM32WLxx_Nucleo\stm32wlxx_nucleo.c - - - - - STM32WLxx_HAL_Driver - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cortex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_gpio.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_iwdg.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart_ex.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_exti.c - - - $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c - - - - CMSIS - - $PROJ_DIR$\..\Src\system_stm32wlxx.c - - - - - Middlewares - - STM32_Secure_Engine - - $PROJ_DIR$\..\..\1_Image_BFU\EWARM\se_interface_appli.o - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s deleted file mode 100644 index 1431e7f3..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s +++ /dev/null @@ -1,509 +0,0 @@ -;******************************************************************************** -;* File Name : startup_stm32wl55xx_cm4.s -;* Author : MCD Application Team -;* Description : M4 core vector table of the STM32WLxxxx devices for the -;* IAR (EWARM) toolchain. -;* -;* This module performs: -;* - Set the initial SP -;* - Set the initial PC == _iar_program_start, -;* - Set the vector table entries with the exceptions ISR -;* address. -;* - Branches to main in the C library (which eventually -;* calls main()). -;* After Reset the Cortex-M4 processor is in Thread mode, -;* priority is Privileged, and the Stack is set to Main. -;******************************************************************************** -;* -;* Copyright (c) 2020 STMicroelectronics. All rights reserved. -;* -;* This software component is licensed by ST under 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: -;* opensource.org/licenses/Apache-2.0 -; -;******************************************************************************* -; -; -; The modules in this file are included in the libraries, and may be replaced -; by any user-defined modules that define the PUBLIC symbol _program_start or -; a user defined start symbol. -; To override the cstartup defined in the library, simply add your modified -; version to the workbench project. -; -; The vector table is normally located at address 0. -; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. -; The name "__vector_table" has special meaning for C-SPY: -; it is where the SP start value is found, and the NVIC vector -; table register (VTOR) is initialized to this address if != 0. -; -; Cortex-M version -; - - MODULE ?cstartup - - ;; Forward declaration of sections. - SECTION CSTACK:DATA:NOROOT(3) - - SECTION .intvec:CODE:NOROOT(2) - - EXTERN __iar_program_start - EXTERN SystemInit - PUBLIC __vector_table - - DATA -__vector_table - DCD sfe(CSTACK) - DCD Reset_Handler ; Reset Handler - - DCD NMI_Handler ; NMI Handler - DCD HardFault_Handler ; Hard Fault Handler - DCD MemManage_Handler ; MPU Fault Handler - DCD BusFault_Handler ; Bus Fault Handler - DCD UsageFault_Handler ; Usage Fault Handler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD SVC_Handler ; SVCall Handler - DCD DebugMon_Handler ; Debug Monitor Handler - DCD 0 ; Reserved - DCD PendSV_Handler ; PendSV Handler - DCD SysTick_Handler ; SysTick Handler - - ; External Interrupts - DCD WWDG_IRQHandler ; Window WatchDog - DCD PVD_PVM_IRQHandler ; PVD and PVM Interrupt - DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSRU Interrupts - DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt - DCD FLASH_IRQHandler ; FLASH global Interrupt - DCD RCC_IRQHandler ; RCC Interrupt - DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt - DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt - DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt - DCD EXTI3_IRQHandler ; EXTI Line 3 Interrupt - DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt - DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt - DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt - DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt - DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt - DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt - DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt - DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt - DCD ADC_IRQHandler ; ADC Interrupt - DCD DAC_IRQHandler ; DAC Interrupt - DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV Interrupt - DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts - DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt - DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt - DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt - DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts - DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt - DCD TIM2_IRQHandler ; TIM2 Global Interrupt - DCD TIM16_IRQHandler ; TIM16 Global Interrupt - DCD TIM17_IRQHandler ; TIM17 Global Interrupt - DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt - DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt - DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt - DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt - DCD SPI1_IRQHandler ; SPI1 Interrupt - DCD SPI2_IRQHandler ; SPI2 Interrupt - DCD USART1_IRQHandler ; USART1 Interrupt - DCD USART2_IRQHandler ; USART2 Interrupt - DCD LPUART1_IRQHandler ; LPUART1 Interrupt - DCD LPTIM1_IRQHandler ; LPTIM1 Global Interrupt - DCD LPTIM2_IRQHandler ; LPTIM2 Global Interrupt - DCD EXTI15_10_IRQHandler ; EXTI Lines [15:10] Interrupt - DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt - DCD LPTIM3_IRQHandler ; LPTIM3 Global Interrupt - DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt - DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt - DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt - DCD HSEM_IRQHandler ; HSEM0 Interrupt - DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt - DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt - DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt - DCD AES_IRQHandler ; AES Interrupt - DCD RNG_IRQHandler ; RNG1 Interrupt - DCD PKA_IRQHandler ; PKA Interrupt - DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt - DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt - DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt - DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt - DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt - DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt - DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt - DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; Default interrupt handlers. -;; - THUMB - - PUBWEAK Reset_Handler - SECTION .text:CODE:NOROOT:REORDER(2) -Reset_Handler - LDR R0, =SystemInit - BLX R0 - LDR R0, =__iar_program_start - BX R0 - - PUBWEAK NMI_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -NMI_Handler - B NMI_Handler - - PUBWEAK HardFault_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -HardFault_Handler - B HardFault_Handler - - PUBWEAK MemManage_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -MemManage_Handler - B MemManage_Handler - - PUBWEAK BusFault_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -BusFault_Handler - B BusFault_Handler - - PUBWEAK UsageFault_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -UsageFault_Handler - B UsageFault_Handler - - PUBWEAK SVC_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -SVC_Handler - B SVC_Handler - - PUBWEAK DebugMon_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -DebugMon_Handler - B DebugMon_Handler - - PUBWEAK PendSV_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -PendSV_Handler - B PendSV_Handler - - PUBWEAK SysTick_Handler - SECTION .text:CODE:NOROOT:REORDER(1) -SysTick_Handler - B SysTick_Handler - - PUBWEAK WWDG_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -WWDG_IRQHandler - B WWDG_IRQHandler - - PUBWEAK PVD_PVM_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -PVD_PVM_IRQHandler - B PVD_PVM_IRQHandler - - PUBWEAK TAMP_STAMP_LSECSS_SSRU_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TAMP_STAMP_LSECSS_SSRU_IRQHandler - B TAMP_STAMP_LSECSS_SSRU_IRQHandler - - PUBWEAK RTC_WKUP_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RTC_WKUP_IRQHandler - B RTC_WKUP_IRQHandler - - PUBWEAK FLASH_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -FLASH_IRQHandler - B FLASH_IRQHandler - - PUBWEAK RCC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RCC_IRQHandler - B RCC_IRQHandler - - PUBWEAK EXTI0_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI0_IRQHandler - B EXTI0_IRQHandler - - PUBWEAK EXTI1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI1_IRQHandler - B EXTI1_IRQHandler - - PUBWEAK EXTI2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI2_IRQHandler - B EXTI2_IRQHandler - - PUBWEAK EXTI3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI3_IRQHandler - B EXTI3_IRQHandler - - PUBWEAK EXTI4_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI4_IRQHandler - B EXTI4_IRQHandler - - PUBWEAK DMA1_Channel1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel1_IRQHandler - B DMA1_Channel1_IRQHandler - - PUBWEAK DMA1_Channel2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel2_IRQHandler - B DMA1_Channel2_IRQHandler - - PUBWEAK DMA1_Channel3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel3_IRQHandler - B DMA1_Channel3_IRQHandler - - PUBWEAK DMA1_Channel4_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel4_IRQHandler - B DMA1_Channel4_IRQHandler - - PUBWEAK DMA1_Channel5_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel5_IRQHandler - B DMA1_Channel5_IRQHandler - - PUBWEAK DMA1_Channel6_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel6_IRQHandler - B DMA1_Channel6_IRQHandler - - PUBWEAK DMA1_Channel7_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA1_Channel7_IRQHandler - B DMA1_Channel7_IRQHandler - - PUBWEAK ADC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -ADC_IRQHandler - B ADC_IRQHandler - - PUBWEAK DAC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DAC_IRQHandler - B DAC_IRQHandler - - PUBWEAK C2SEV_PWR_C2H_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -C2SEV_PWR_C2H_IRQHandler - B C2SEV_PWR_C2H_IRQHandler - - PUBWEAK COMP_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -COMP_IRQHandler - B COMP_IRQHandler - - PUBWEAK EXTI9_5_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI9_5_IRQHandler - B EXTI9_5_IRQHandler - - PUBWEAK TIM1_BRK_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_BRK_IRQHandler - B TIM1_BRK_IRQHandler - - PUBWEAK TIM1_UP_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_UP_IRQHandler - B TIM1_UP_IRQHandler - - PUBWEAK TIM1_TRG_COM_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_TRG_COM_IRQHandler - B TIM1_TRG_COM_IRQHandler - - PUBWEAK TIM1_CC_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM1_CC_IRQHandler - B TIM1_CC_IRQHandler - - PUBWEAK TIM2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM2_IRQHandler - B TIM2_IRQHandler - - PUBWEAK TIM16_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM16_IRQHandler - B TIM16_IRQHandler - - PUBWEAK TIM17_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -TIM17_IRQHandler - B TIM17_IRQHandler - - PUBWEAK I2C1_EV_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C1_EV_IRQHandler - B I2C1_EV_IRQHandler - - PUBWEAK I2C1_ER_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C1_ER_IRQHandler - B I2C1_ER_IRQHandler - - PUBWEAK I2C2_EV_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C2_EV_IRQHandler - B I2C2_EV_IRQHandler - - PUBWEAK I2C2_ER_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C2_ER_IRQHandler - B I2C2_ER_IRQHandler - - PUBWEAK SPI1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SPI1_IRQHandler - B SPI1_IRQHandler - - PUBWEAK SPI2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SPI2_IRQHandler - B SPI2_IRQHandler - - PUBWEAK USART1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -USART1_IRQHandler - B USART1_IRQHandler - - PUBWEAK USART2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -USART2_IRQHandler - B USART2_IRQHandler - - PUBWEAK LPUART1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPUART1_IRQHandler - B LPUART1_IRQHandler - - PUBWEAK LPTIM1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPTIM1_IRQHandler - B LPTIM1_IRQHandler - - PUBWEAK LPTIM2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPTIM2_IRQHandler - B LPTIM2_IRQHandler - - PUBWEAK EXTI15_10_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -EXTI15_10_IRQHandler - B EXTI15_10_IRQHandler - - PUBWEAK RTC_Alarm_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RTC_Alarm_IRQHandler - B RTC_Alarm_IRQHandler - - PUBWEAK LPTIM3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -LPTIM3_IRQHandler - B LPTIM3_IRQHandler - - PUBWEAK SUBGHZSPI_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SUBGHZSPI_IRQHandler - B SUBGHZSPI_IRQHandler - - PUBWEAK IPCC_C1_RX_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -IPCC_C1_RX_IRQHandler - B IPCC_C1_RX_IRQHandler - - PUBWEAK IPCC_C1_TX_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -IPCC_C1_TX_IRQHandler - B IPCC_C1_TX_IRQHandler - - PUBWEAK HSEM_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -HSEM_IRQHandler - B HSEM_IRQHandler - - PUBWEAK I2C3_EV_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C3_EV_IRQHandler - B I2C3_EV_IRQHandler - - PUBWEAK I2C3_ER_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -I2C3_ER_IRQHandler - B I2C3_ER_IRQHandler - - PUBWEAK SUBGHZ_Radio_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -SUBGHZ_Radio_IRQHandler - B SUBGHZ_Radio_IRQHandler - - PUBWEAK AES_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -AES_IRQHandler - B AES_IRQHandler - - PUBWEAK RNG_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -RNG_IRQHandler - B RNG_IRQHandler - - PUBWEAK PKA_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -PKA_IRQHandler - B PKA_IRQHandler - - PUBWEAK DMA2_Channel1_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel1_IRQHandler - B DMA2_Channel1_IRQHandler - - PUBWEAK DMA2_Channel2_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel2_IRQHandler - B DMA2_Channel2_IRQHandler - - PUBWEAK DMA2_Channel3_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel3_IRQHandler - B DMA2_Channel3_IRQHandler - - PUBWEAK DMA2_Channel4_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel4_IRQHandler - B DMA2_Channel4_IRQHandler - - PUBWEAK DMA2_Channel5_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel5_IRQHandler - B DMA2_Channel5_IRQHandler - - PUBWEAK DMA2_Channel6_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel6_IRQHandler - B DMA2_Channel6_IRQHandler - - PUBWEAK DMA2_Channel7_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMA2_Channel7_IRQHandler - B DMA2_Channel7_IRQHandler - - PUBWEAK DMAMUX1_OVR_IRQHandler - SECTION .text:CODE:NOROOT:REORDER(1) -DMAMUX1_OVR_IRQHandler - B DMAMUX1_OVR_IRQHandler - - END - -;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf deleted file mode 100644 index 0726aa48..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf +++ /dev/null @@ -1,43 +0,0 @@ -/*###ICF### Set of symbols used in UserApp project ****/ - -define memory mem with size = 4G; - -/******************************************************************************/ -/* Include of SBSFU symbols file */ -/* (Project>Options>Linker>Extra Options --config_search option is used to */ -/* specify the the directory to search for include files */ -/******************************************************************************/ -include "mapping_sbsfu.icf"; -include "mapping_fwimg.icf"; - -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = __ICFEDIT_SLOT_Active_1_start__ + 512; -define symbol __ICFEDIT_region_ROM_end__ = __ICFEDIT_SLOT_Active_1_end__ ; -define symbol __ICFEDIT_region_RAM_start__ = __ICFEDIT_SE_region_RAM_end__ + 1; -define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF; - -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; - -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -/* to make sure the binary size is a multiple of the AES block size (16 bytes) and L4 flash writing unit (8 bytes) */ -define root section aes_block_padding with alignment=16 -{ -udata8 "Force Alignment"; -pad_to 16; -}; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -place at address mem:__ICFEDIT_region_ROM_start__ { readonly section .intvec }; - -place in ROM_region { readonly, last section aes_block_padding }; -place in RAM_region { readwrite, block CSTACK, block HEAP }; - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h deleted file mode 100644 index 6b8db4f7..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - ****************************************************************************** - * @file stm32wlxx_nucleo_conf.h - * @author MCD Application Team - * @brief STM32WLxx_Nucleo board configuration file. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32WLXX_NUCLEO_CONF_H -#define STM32WLXX_NUCLEO_CONF_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32wlxx_hal.h" - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup STM32WLXX_NUCLEO - * @{ - */ - -/** @defgroup STM32WLXX_NUCLEO_CONFIG CONFIG - * @{ - */ - -/** @defgroup STM32WLXX_NUCLEO_CONFIG_Exported_Constants Exported Constants - * @{ - */ -/* COM usage define */ -#define USE_BSP_COM_FEATURE 0U - -/* COM log define */ -#define USE_COM_LOG 0U - -/* IRQ priorities */ -#define BSP_BUTTON_SWx_IT_PRIORITY 15U - -/* Radio maximum wakeup time (in ms) */ -#define RF_WAKEUP_TIME 100U - -/* Indicates whether or not TCXO is supported by the board - * 0: TCXO not supported - * 1: TCXO supported - */ -#define IS_TCXO_SUPPORTED 0U - -/* Indicates whether or not DCDC is supported by the board - * 0: DCDC not supported - * 1: DCDC supported - */ -#define IS_DCDC_SUPPORTED 1U - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32WLXX_NUCLEO_CONF_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/tkms_app.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/tkms_app.h deleted file mode 100644 index e6a35163..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/tkms_app.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - ****************************************************************************** - * @file tkms_app.h - * @author MCD Application Team - * @brief This file contains definitions for tkms application examples. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef KMS_APP_H -#define KMS_APP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "app_sfu.h" - -/* Exported macros -----------------------------------------------------------*/ -#if defined(SFU_IWDG_PROTECT_ENABLE) -/* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload register */ -#define INVOKE_SCHEDULE_NEEDS() \ - do { \ - WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); \ - } while(0); -#else -#define INVOKE_SCHEDULE_NEEDS() \ - do { \ - ; \ - } while(0); -#endif /* SFU_IWDG_PROTECT_ENABLE */ - - - -/* Exported functions ------------------------------------------------------- */ -void tkms_app_menu(void); -void tkms_buff2str(uint8_t *pbuff, uint8_t *pstr, uint32_t length); - -CK_RV tkms_app_encrypt_decrypt_aes_gcm(uint32_t length, uint8_t *pClearMessage); -CK_RV tkms_app_encrypt_decrypt_aes_cbc(uint32_t length, uint8_t *pClearMessage); -CK_RV tkms_app_sign_verify_rsa(uint32_t length, uint8_t *pMessage); -CK_RV tkms_app_derive_key(uint32_t length, uint8_t *pMessage); - -#ifdef __cplusplus -} -#endif - -#endif /* KMS_APP_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/Project.uvoptx deleted file mode 100644 index 206b7123..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/Project.uvoptx +++ /dev/null @@ -1,796 +0,0 @@ - - - - 1.0 - -
      ### uVision Project, (C) Keil Software
      - - - *.c - *.s*; *.src; *.a* - *.obj; *.o - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - STM32WL55JC_Nucleo_1_Image_UserApp - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - STM32WL55JC_Nucleo/List\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 18 - - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 6 - - - - - - - - - - .\STM32WL_CM4.ini - STLink\ST-LINKIII-KEIL_SWO.dll - - - - 0 - UL2CM3 - UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) - - - 0 - ST-LINKIII-KEIL_SWO - UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=98,207,509,709,0)(1007=673,180,880,401,0)(1008=566,409,942,645,0)(1009=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0) - - - - - 0 - 0 - 55 - 1 -
      134345422
      - 0 - 0 - 0 - 0 - 0 - 1 - C:\git\wl_master\Firmware\Projects\NUCLEO-WL55JC\Applications\BFU_1_Image\1_Image_UserApp\Src\mpu.c - - \\UserApp_M0\../Src/mpu.c\55 -
      - - 1 - 0 - 141 - 1 -
      134337248
      - 0 - 0 - 0 - 0 - 0 - 1 - .\startup_stm32wl55xx_cm4.s - - \\UserApp_M0\startup_stm32wl55xx_cm4.s\141 -
      - - 2 - 0 - 400 - 1 -
      134346614
      - 0 - 0 - 0 - 0 - 0 - 1 - ../Src/test_protections.c - - \\UserApp_M0\../Src/test_protections.c\400 -
      -
      - - - 1 - 2 - 0x2000A400 - 0 - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - System Viewer\DBGMCU - 35904 - - - System Viewer\NVIC - 35901 - - - System Viewer\SCB - 35905 - - - System Viewer\SYSCFG - 35903 - - - System Viewer\SYSCFG_continue - 35902 - - -
      -
      - - - Application/MDK-ARM - 0 - 0 - 0 - 0 - - 1 - 1 - 2 - 0 - 0 - 0 - .\startup_stm32wl55xx_cm4.s - startup_stm32wl55xx_cm4.s - 0 - 0 - - - - - Application/User - 0 - 0 - 0 - 0 - - 2 - 2 - 1 - 0 - 0 - 0 - ../Src/com.c - com.c - 0 - 0 - - - 2 - 3 - 1 - 0 - 0 - 0 - ../Src/common.c - common.c - 0 - 0 - - - 2 - 4 - 1 - 0 - 0 - 0 - ../Src/flash_if.c - flash_if.c - 0 - 0 - - - 2 - 5 - 1 - 0 - 0 - 0 - ../Src/fw_update_app.c - fw_update_app.c - 0 - 0 - - - 2 - 6 - 1 - 0 - 0 - 0 - ../Src/kms_object_update_app.c - kms_object_update_app.c - 0 - 0 - - - 2 - 7 - 1 - 0 - 0 - 0 - ../Src/main.c - main.c - 0 - 0 - - - 2 - 8 - 1 - 0 - 0 - 0 - ../Src/se_user_code.c - se_user_code.c - 0 - 0 - - - 2 - 9 - 1 - 0 - 0 - 0 - ../Src/stm32wlxx_it.c - stm32wlxx_it.c - 0 - 0 - - - 2 - 10 - 1 - 0 - 0 - 0 - ../Src/test_protections.c - test_protections.c - 0 - 0 - - - 2 - 11 - 1 - 0 - 0 - 0 - ../Src/tkms_app.c - tkms_app.c - 0 - 0 - - - 2 - 12 - 1 - 0 - 0 - 0 - ../Src/tkms_app_derive_key.c - tkms_app_derive_key.c - 0 - 0 - - - 2 - 13 - 1 - 0 - 0 - 0 - ../Src/tkms_app_encrypt_decrypt.c - tkms_app_encrypt_decrypt.c - 0 - 0 - - - 2 - 14 - 1 - 0 - 0 - 0 - ../Src/tkms_app_sign_verify.c - tkms_app_sign_verify.c - 0 - 0 - - - 2 - 15 - 1 - 0 - 0 - 0 - ../Src/ymodem.c - ymodem.c - 0 - 0 - - - - - Doc - 1 - 0 - 0 - 0 - - 3 - 16 - 5 - 0 - 0 - 0 - ../readme.txt - readme.txt - 0 - 0 - - - - - Drivers/BSP/STM32WLxx_Nucleo - 0 - 0 - 0 - 0 - - 4 - 17 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c - stm32wlxx_nucleo.c - 0 - 0 - - - - - Drivers/STM32WLxx_HAL_Driver - 0 - 0 - 0 - 0 - - 5 - 18 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c - stm32wlxx_hal.c - 0 - 0 - - - 5 - 19 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c - stm32wlxx_hal_cortex.c - 0 - 0 - - - 5 - 20 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - stm32wlxx_hal_crc.c - 0 - 0 - - - 5 - 21 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - stm32wlxx_hal_crc_ex.c - 0 - 0 - - - 5 - 22 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c - stm32wlxx_hal_dma.c - 0 - 0 - - - 5 - 23 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c - stm32wlxx_hal_dma_ex.c - 0 - 0 - - - 5 - 24 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c - stm32wlxx_hal_exti.c - 0 - 0 - - - 5 - 25 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - stm32wlxx_hal_flash.c - 0 - 0 - - - 5 - 26 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - stm32wlxx_hal_flash_ex.c - 0 - 0 - - - 5 - 27 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c - stm32wlxx_hal_gpio.c - 0 - 0 - - - 5 - 28 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c - stm32wlxx_hal_iwdg.c - 0 - 0 - - - 5 - 29 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c - stm32wlxx_hal_pwr.c - 0 - 0 - - - 5 - 30 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c - stm32wlxx_hal_pwr_ex.c - 0 - 0 - - - 5 - 31 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c - stm32wlxx_hal_rcc.c - 0 - 0 - - - 5 - 32 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c - stm32wlxx_hal_rcc_ex.c - 0 - 0 - - - 5 - 33 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c - stm32wlxx_hal_rtc.c - 0 - 0 - - - 5 - 34 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c - stm32wlxx_hal_rtc_ex.c - 0 - 0 - - - 5 - 35 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c - stm32wlxx_hal_uart.c - 0 - 0 - - - 5 - 36 - 1 - 0 - 0 - 0 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c - stm32wlxx_hal_uart_ex.c - 0 - 0 - - - - - Drivers/CMSIS - 0 - 0 - 0 - 0 - - 6 - 37 - 1 - 0 - 0 - 0 - ../Src/system_stm32wlxx.c - system_stm32wlxx.c - 0 - 0 - - - - - Middlewares/STM32_Secure_Engine - 0 - 0 - 0 - 0 - - 7 - 38 - 3 - 0 - 0 - 0 - ..\..\1_Image_BFU\MDK-ARM\STM32WL55JC_Nucleo\Exe\se_interface_appli.txt - se_interface_appli.txt - 0 - 0 - - - - - ::CMSIS - 0 - 0 - 0 - 1 - - -
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/Project.uvprojx deleted file mode 100644 index 75757b28..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/Project.uvprojx +++ /dev/null @@ -1,627 +0,0 @@ - - - - 2.1 - -
      ### uVision Project, (C) Keil Software
      - - - - STM32WL55JC_Nucleo_1_Image_UserApp - 0x4 - ARM-ADS - 6120000::V6.12::.\ARMCLANG - 1 - - - STM32WL55JCIx:CM4 - STMicroelectronics - Keil.STM32WLxx_DFP.1.0.4 - http://www.keil.com/pack - IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE - - - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) - 0 - $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h - - - - - - - - - - $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd - 0 - 0 - - - - - - - 0 - 0 - 0 - 0 - 1 - - .\STM32WL55JC_Nucleo\Exe\ - UserApp - 1 - 0 - 0 - 1 - 1 - STM32WL55JC_Nucleo/List\ - 1 - 0 - 0 - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 0 - 0 - - - 0 - 0 - 0 - 0 - - - 1 - 1 - fromelf #L --bincombined --output=$L../../@L.bin - .\..\..\1_Image_SECoreBin\MDK-ARM\postbuild.bat . #L @L.bin 1 1 - 0 - 0 - 0 - 0 - - 1 - - - - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 3 - - - 0 - - - SARMCM3.DLL - -REMAP -MPU - DCM.DLL - -pCM4 - SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 - - - - 1 - 0 - 0 - 0 - 16 - - - - - 1 - 0 - 0 - 1 - 1 - 4096 - - 1 - BIN\UL2CM3.DLL - - - - - - 0 - - - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - "Cortex-M4" - - 0 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 1 - 0 - 0 - 0 - 3 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 1 - 0x8000000 - 0x40000 - - - 0 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x0 - 0x0 - - - 1 - 0x8000000 - 0x40000 - - - 1 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x0 - 0x0 - - - 0 - 0x20000000 - 0x10000 - - - 0 - 0x0 - 0x0 - - - - - - 1 - 7 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 3 - 0 - 0 - 1 - 0 - 0 - 5 - 3 - 0 - 0 - 0 - 0 - 0 - - - USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED,DISABLE_IMAGE_STATE_HANDLING - - ../Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../1_Image_SECoreBin/Inc;../../1_Image_BFU/BFU/App;../../Linker_Common/MDK-ARM;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface;../../../../../../Drivers/BSP/STM32WLxx_Nucleo - - - - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - 0 - 1 - 0 - - - - .\UserApp.sct - - - - - - - - - - - Application/MDK-ARM - - - startup_stm32wl55xx_cm4.s - 2 - .\startup_stm32wl55xx_cm4.s - - - - - Application/User - - - com.c - 1 - ../Src/com.c - - - common.c - 1 - ../Src/common.c - - - flash_if.c - 1 - ../Src/flash_if.c - - - fw_update_app.c - 1 - ../Src/fw_update_app.c - - - kms_object_update_app.c - 1 - ../Src/kms_object_update_app.c - - - main.c - 1 - ../Src/main.c - - - se_user_code.c - 1 - ../Src/se_user_code.c - - - stm32wlxx_it.c - 1 - ../Src/stm32wlxx_it.c - - - test_protections.c - 1 - ../Src/test_protections.c - - - tkms_app.c - 1 - ../Src/tkms_app.c - - - tkms_app_derive_key.c - 1 - ../Src/tkms_app_derive_key.c - - - tkms_app_encrypt_decrypt.c - 1 - ../Src/tkms_app_encrypt_decrypt.c - - - tkms_app_sign_verify.c - 1 - ../Src/tkms_app_sign_verify.c - - - ymodem.c - 1 - ../Src/ymodem.c - - - - - Doc - - - readme.txt - 5 - ../readme.txt - - - - - Drivers/BSP/STM32WLxx_Nucleo - - - stm32wlxx_nucleo.c - 1 - ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c - - - - - Drivers/STM32WLxx_HAL_Driver - - - stm32wlxx_hal.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c - - - stm32wlxx_hal_cortex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c - - - stm32wlxx_hal_crc.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - - - stm32wlxx_hal_crc_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - - - stm32wlxx_hal_dma.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c - - - stm32wlxx_hal_dma_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c - - - stm32wlxx_hal_exti.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c - - - stm32wlxx_hal_flash.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - - - stm32wlxx_hal_flash_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - - - stm32wlxx_hal_gpio.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c - - - stm32wlxx_hal_iwdg.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c - - - stm32wlxx_hal_pwr.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c - - - stm32wlxx_hal_pwr_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c - - - stm32wlxx_hal_rcc.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c - - - stm32wlxx_hal_rcc_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c - - - stm32wlxx_hal_rtc.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c - - - stm32wlxx_hal_rtc_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c - - - stm32wlxx_hal_uart.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c - - - stm32wlxx_hal_uart_ex.c - 1 - ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c - - - - - Drivers/CMSIS - - - system_stm32wlxx.c - 1 - ../Src/system_stm32wlxx.c - - - - - Middlewares/STM32_Secure_Engine - - - se_interface_appli.txt - 3 - ..\..\1_Image_BFU\MDK-ARM\STM32WL55JC_Nucleo\Exe\se_interface_appli.txt - - - - - ::CMSIS - - - - - - - - - - - - - - - - - - -
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/UserApp.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/UserApp.sct deleted file mode 100644 index 4ab8c3d2..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/UserApp.sct +++ /dev/null @@ -1,29 +0,0 @@ -#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0plus -E -xc -; ************************************************************* -; *** Scatter-Loading Description File generated by uVision *** -; ************************************************************* -#include "..\..\Linker_Common\MDK-ARM\mapping_sbsfu.h" -#include "..\..\Linker_Common\MDK-ARM\mapping_fwimg.h" - -LR_ROM (SLOT_ACTIVE_1_START + 0x200) { ; 0x200 = IMAGE_OFFSET - vector_start (SLOT_ACTIVE_1_START + 0x200) FIXED VECTOR_SIZE { - *.o (RESET, +First) - } - ROM_region +0 { - *(InRoot$$Sections) - .ANY (+RO) - } -; SBSFU RAM area is reused for UserApp - RAM_region SB_REGION_RAM_START SB_RAM_REGION_SIZE { - .ANY (STACK) - .ANY (HEAP) - .ANY (+RW +ZI) - } -} - -; extra ROM region to make sure the binary size is a multiple of the AES block size (16 bytes) and L4 flash writing unit (8 bytes) -LR_ROM1(+0) ALIGN(16) { - ForAlignment +0 { - startup_stm32wl55xx_cm4.o (ALIGNTOAESBLOCK,+Last) - } -} diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/.cproject deleted file mode 100644 index aee28e0e..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/.cproject +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/.project deleted file mode 100644 index aa5cadf4..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/.project +++ /dev/null @@ -1,226 +0,0 @@ - - - 1_Image_UserApp - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - com.st.stm32cube.ide.mcu.MCUProjectNature - org.eclipse.cdt.core.cnature - com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature - com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature - com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature - com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature - com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature - com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature - com.st.stm32cube.ide.mcu.MCURootProjectNature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - - - Doc/readme.txt - 1 - $%7BPARENT-1-PROJECT_LOC%7D/readme.txt - - - Application/User/com.c - 1 - PARENT-1-PROJECT_LOC/Src/com.c - - - Application/User/common.c - 1 - PARENT-1-PROJECT_LOC/Src/common.c - - - Application/User/flash_if.c - 1 - PARENT-1-PROJECT_LOC/Src/flash_if.c - - - Application/User/fw_update_app.c - 1 - PARENT-1-PROJECT_LOC/Src/fw_update_app.c - - - Application/User/kms_object_update_app.c - 1 - PARENT-1-PROJECT_LOC/Src/kms_object_update_app.c - - - Application/User/main.c - 1 - PARENT-1-PROJECT_LOC/Src/main.c - - - Application/User/se_user_code.c - 1 - PARENT-1-PROJECT_LOC/Src/se_user_code.c - - - Application/User/stm32wlxx_it.c - 1 - PARENT-1-PROJECT_LOC/Src/stm32wlxx_it.c - - - Application/User/test_protections.c - 1 - PARENT-1-PROJECT_LOC/Src/test_protections.c - - - Application/User/tkms_app.c - 1 - PARENT-1-PROJECT_LOC/Src/tkms_app.c - - - Application/User/tkms_app_derive_key.c - 1 - PARENT-1-PROJECT_LOC/Src/tkms_app_derive_key.c - - - Application/User/tkms_app_encrypt_decrypt.c - 1 - PARENT-1-PROJECT_LOC/Src/tkms_app_encrypt_decrypt.c - - - Application/User/tkms_app_sign_verify.c - 1 - PARENT-1-PROJECT_LOC/Src/tkms_app_sign_verify.c - - - Application/User/ymodem.c - 1 - PARENT-1-PROJECT_LOC/Src/ymodem.c - - - Drivers/CMSIS/system_stm32wlxx.c - 1 - PARENT-1-PROJECT_LOC/Src/system_stm32wlxx.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cortex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_dma.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_dma_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_exti.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gpio.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gtzc.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gtzc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_iwdg.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c - - - Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart_ex.c - 1 - PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c - - - Middlewares/STM32_Secure_Engine/se_interface_app.o - 1 - PARENT-2-PROJECT_LOC/1_Image_BFU/STM32CubeIDE/Debug/se_interface_app.o - - - Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c - 1 - PARENT-6-PROJECT_LOC/Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c - - - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/flash_if.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/flash_if.c deleted file mode 100644 index fe37d3ee..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/flash_if.c +++ /dev/null @@ -1,361 +0,0 @@ -/** - ****************************************************************************** - * @file flash_if.c - * @author MCD Application Team - * @brief FLASH Interface module. - * This file provides set of firmware functions to manage Flash - * Interface functionalities. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/** @addtogroup USER_APP User App Example - * @{ - */ - -/** @addtogroup USER_APP_COMMON Common - * @{ - */ -/* Includes ------------------------------------------------------------------*/ -#include "flash_if.h" -#include "string.h" -#include - -/* Uncomment the line below if you want some debug logs */ -#define FLASH_IF_DBG -#ifdef FLASH_IF_DBG -#define FLASH_IF_TRACE printf -#else -#define FLASH_IF_TRACE(...) -#endif /* FLASH_IF_DBG */ - - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -#define NB_PAGE_SECTOR_PER_ERASE 2U /*!< Nb page erased per erase */ -#define EXTERNAL_FLASH_ADDRESS 0x90000000U -#define BLOC_64_KBYTES 0x10000U - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ - - -/* Private function prototypes -----------------------------------------------*/ -static uint32_t GetPage(uint32_t uAddr); -static HAL_StatusTypeDef FLASH_INT_If_Clear_Error(void); - -/* Public functions : wrapper ---------------------------------------------------------*/ - -/** - * @brief Initialize internal and external flash interface (OSPI/QSPI) - * @param none - * @retval HAL status. - */ -HAL_StatusTypeDef FLASH_If_Init(void) -{ - HAL_StatusTypeDef e_ret_status = HAL_OK; - - e_ret_status = FLASH_INT_Init(); - if (e_ret_status == HAL_OK) - { - e_ret_status = FLASH_EXT_Init(); - } - return e_ret_status; -} -/** - * @brief Depending on start address, this function will call internal or external (OSPI/QSPI) flash driver - * @param pStart: flash address to be erased - * @param uLength: number of bytes - * @retval HAL status. - */ -HAL_StatusTypeDef FLASH_If_Erase_Size(void *pStart, uint32_t uLength) -{ - /* Check Flash start address */ - if ((uint32_t) pStart < EXTERNAL_FLASH_ADDRESS) - { - return FLASH_INT_If_Erase_Size(pStart, uLength); - } - else - { - return FLASH_EXT_If_Erase_Size(pStart, uLength); - } -} - -/** - * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver - * @param pDestination: flash address to write - * @param pSource: pointer on buffer with data to write - * @param uLength: number of bytes - * @retval HAL Status. - */ -HAL_StatusTypeDef FLASH_If_Write(void *pDestination, const void *pSource, uint32_t uLength) -{ - /* Check Flash destination address */ - if ((uint32_t) pDestination < EXTERNAL_FLASH_ADDRESS) - { - return FLASH_INT_If_Write(pDestination, pSource, uLength); - } - else - { - return FLASH_EXT_If_Write(pDestination, pSource, uLength); - } -} - -/** - * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver - * @brief Depending on source address, this function will call internal or external (OSPI/QSPI) flash driver - * @param pDestination: pointer on buffer to store data - * @param pSource: flash address to read - * @param uLength: number of bytes - * @retval HAL Status. - */ -HAL_StatusTypeDef FLASH_If_Read(void *pDestination, const void *pSource, uint32_t uLength) -{ - /* Check Flash source address */ - if ((uint32_t) pSource < EXTERNAL_FLASH_ADDRESS) - { - return FLASH_INT_If_Read(pDestination, pSource, uLength); - } - else - { - return FLASH_EXT_If_Read(pDestination, pSource, uLength); - } -} - -/* Public functions : internal flash --------------------------------------------------------- */ -/** - * @brief This function initialize the internal flash interface if required - * @param none - * @retval HAL status. - */ -HAL_StatusTypeDef FLASH_INT_Init(void) -{ - return HAL_OK; -} - -/** - * @brief This function does an erase of n (depends on Length) pages in user flash area - * @param pStart: Start of user flash area - * @param uLength: number of bytes. - * @retval HAL status. - */ -HAL_StatusTypeDef FLASH_INT_If_Erase_Size(void *pStart, uint32_t uLength) -{ - uint32_t page_error = 0U; - uint32_t uStart = (uint32_t)pStart; - FLASH_EraseInitTypeDef x_erase_init; - HAL_StatusTypeDef e_ret_status = HAL_ERROR; - uint32_t first_page = 0U; - uint32_t nb_pages = 0U; - uint32_t chunk_nb_pages; - - /* Clear error flags raised during previous operation */ - e_ret_status = FLASH_INT_If_Clear_Error(); - - if (e_ret_status == HAL_OK) - { - /* Unlock the Flash to enable the flash control register access *************/ - if (HAL_FLASH_Unlock() == HAL_OK) - { - first_page = GetPage(uStart); - /* Get the number of pages to erase from 1st page */ - nb_pages = GetPage(uStart + uLength - 1U) - first_page + 1U; - x_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; - /* Erase flash per NB_PAGE_SECTOR_PER_ERASE to avoid watch-dog */ - do - { - chunk_nb_pages = (nb_pages >= NB_PAGE_SECTOR_PER_ERASE) ? NB_PAGE_SECTOR_PER_ERASE : nb_pages; - x_erase_init.Page = first_page; - x_erase_init.NbPages = chunk_nb_pages; - first_page += chunk_nb_pages; - nb_pages -= chunk_nb_pages; - if (HAL_FLASHEx_Erase(&x_erase_init, &page_error) != HAL_OK) - { - HAL_FLASH_GetError(); - e_ret_status = HAL_ERROR; - } - /* Refresh Watchdog */ - WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); - } while (nb_pages > 0); - /* Lock the Flash to disable the flash control register access (recommended - to protect the FLASH memory against possible unwanted operation) *********/ - HAL_FLASH_Lock(); - - } - else - { - e_ret_status = HAL_ERROR; - } - } - - return e_ret_status; -} - -/** - * @brief This function writes a data buffer in flash (data are 32-bit aligned). - * @note After writing data buffer, the flash content is checked. - * @param pDestination: Start address for target location. It has to be 8 bytes aligned. - * @param pSource: pointer on buffer with data to write - * @param uLength: Length of data buffer in bytes. It has to be 8 bytes aligned. - * @retval HAL Status. - */ -HAL_StatusTypeDef FLASH_INT_If_Write(void *pDestination, const void *pSource, uint32_t uLength) -{ - HAL_StatusTypeDef e_ret_status = HAL_ERROR; - uint32_t i = 0U; - uint32_t pdata = (uint32_t)pSource; - - /* Clear error flags raised during previous operation */ - e_ret_status = FLASH_INT_If_Clear_Error(); - - if (e_ret_status == HAL_OK) - { - /* Unlock the Flash to enable the flash control register access *************/ - if (HAL_FLASH_Unlock() != HAL_OK) - { - return HAL_ERROR; - - } - else - { - /* DataLength must be a multiple of 64 bit */ - for (i = 0U; i < uLength; i += 8U) - { - /* Device voltage range supposed to be [2.7V to 3.6V], the operation will - be done by word */ - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)pDestination, *((uint64_t *)(pdata + i))) - == HAL_OK) - { - /* Check the written value */ - if (*(uint64_t *)pDestination != *(uint64_t *)(pdata + i)) - { - /* Flash content doesn't match SRAM content */ - e_ret_status = HAL_ERROR; - break; - } - /* Increment FLASH Destination address */ - pDestination = (void *)((uint32_t)pDestination + 8U); - } - else - { - /* Error occurred while writing data in Flash memory */ - e_ret_status = HAL_ERROR; - break; - } - } - /* Lock the Flash to disable the flash control register access (recommended - to protect the FLASH memory against possible unwanted operation) *********/ - HAL_FLASH_Lock(); - } - } - return e_ret_status; -} - -/** - * @brief This function reads flash - * @param pDestination: Start address for target location - * @param pSource: flash address to read - * @param uLength: number of bytes - * @retval HAL Status. - */ -HAL_StatusTypeDef FLASH_INT_If_Read(void *pDestination, const void *pSource, uint32_t uLength) -{ - memcpy(pDestination, pSource, uLength); - return HAL_OK; -} - -/* Public functions : external flash ---------------------------------------------------------*/ - -HAL_StatusTypeDef FLASH_EXT_Init(void) -{ - return HAL_OK; -} - -/* No external flash available on this product - ==> return SFU_ERROR */ - -HAL_StatusTypeDef FLASH_EXT_If_Erase_Size(void *pStart, uint32_t uLength) -{ - return HAL_ERROR; -} - -HAL_StatusTypeDef FLASH_EXT_If_Write(void *pDestination, const void *pSource, uint32_t uLength) -{ - return HAL_ERROR; -} - -HAL_StatusTypeDef FLASH_EXT_If_Read(void *pDestination, const void *pSource, uint32_t uLength) -{ - return HAL_ERROR; -} - -/* Private functions ---------------------------------------------------------*/ -/** - * @brief Clear error flags raised during previous operation - * @param None - * @retval HAL Status. - */ -HAL_StatusTypeDef FLASH_INT_If_Clear_Error(void) -{ - HAL_StatusTypeDef ret = HAL_ERROR; - - /* Unlock the Program memory */ - if (HAL_FLASH_Unlock() == HAL_OK) - { - - /* Clear all FLASH flags */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); - /* Unlock the Program memory */ - if (HAL_FLASH_Lock() == HAL_OK) - { - ret = HAL_OK; - } -#ifdef FLASH_IF_DBG - else - { - FLASH_IF_TRACE("[FLASH_IF] Lock failure\r\n"); - } -#endif /* FLASH_IF_DBG */ - } -#ifdef FLASH_IF_DBG - else - { - FLASH_IF_TRACE("[FLASH_IF] Unlock failure\r\n"); - } -#endif /* FLASH_IF_DBG */ - return ret; -} - -/** - * @brief Gets the page of a given address - * @param Addr: Address of the FLASH Memory - * @retval The page of a given address - */ -uint32_t GetPage(uint32_t Addr) -{ - uint32_t page = 0U; - - page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE; - - return page; -} - - -/** - * @} - */ - -/** - * @} - */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/fw_update_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/fw_update_app.c deleted file mode 100644 index 4b945f87..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/fw_update_app.c +++ /dev/null @@ -1,141 +0,0 @@ -/** - ****************************************************************************** - * @file fw_update_app.c - * @author MCD Application Team - * @brief Firmware Update module. - * This file provides set of firmware functions to manage Firmware - * Update functionalities. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ - -#include "se_def.h" -#include "com.h" -#include "common.h" -#include "flash_if.h" -#include "stm32wlxx_hal.h" -#include "stm32wlxx_nucleo.h" -#include "fw_update_app.h" -#include "se_interface_application.h" -#include "sfu_fwimg_regions.h" -#include "string.h" -#if defined(__ARMCC_VERSION) -#include "mapping_sbsfu.h" -#elif defined (__ICCARM__) || defined(__GNUC__) -#include "mapping_export.h" -#endif /* __ARMCC_VERSION */ -#include "ymodem.h" - -/* Private defines -----------------------------------------------------------*/ - - -/* Global variables ----------------------------------------------------------*/ - - -/* Private function prototypes -----------------------------------------------*/ - - -/* Functions Definition ------------------------------------------------------*/ - -/** - * @brief Run FW Update process. - * @param None - * @retval HAL Status. - */ -#if defined(EXTERNAL_LOADER) -void FW_UPDATE_Run(void) -{ - /* Print Firmware Update welcome message */ - printf("\r\n================ New Fw Download =========================\r\n\n"); - - /* Standalone loader communication : execution requested */ - (*(uint32_t *)LOADER_COM_REGION_RAM_START) = STANDALONE_LOADER_BYPASS_REQ; - - NVIC_SystemReset(); -} - -#else -void FW_UPDATE_Run(void) -{ - printf(" Feature not supported ! \r\n"); -} - -#endif - - -#if defined(EXTERNAL_LOADER) -/** - * @brief Run Multiple FW Update process. - * @param None - * @retval None. - */ -void FW_UPDATE_MULTIPLE_RunMenu(void) -{ - printf(" Feature not supported ! \r\n"); -} - -#else -/** - * @brief Run Multiple FW Update process. - * @param None - * @retval None. - */ -void FW_UPDATE_MULTIPLE_RunMenu(void) -{ - printf(" Feature not supported ! \r\n"); -} - -#endif - - -#if defined(EXTERNAL_LOADER) -/** - * @brief Run validation of a FW image menu. - * @param None - * @retval None. - */ -void FW_VALIDATE_RunMenu(void) -{ - printf(" Feature not supported ! \r\n"); -} - -#else -/** - * @brief Run validation of a FW image menu. - * @param None - * @retval None. - */ -void FW_VALIDATE_RunMenu(void) -{ - printf(" Feature not supported ! \r\n"); -} - -#endif - - - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/se_user_code.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/se_user_code.c deleted file mode 100644 index 18f9a54d..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/se_user_code.c +++ /dev/null @@ -1,179 +0,0 @@ -/** - ****************************************************************************** - * @file se_user_code.c - * @author MCD Application Team - * @brief Secure Engine User code example module. - * This file demonstrates how to call user defined services running - * in Secure Engine. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "se_def.h" -#include "com.h" -#include "common.h" -#include "stm32wlxx_hal.h" -#include "stm32wlxx_nucleo.h" -#include "se_user_code.h" -#include "se_interface_application.h" -#include "sfu_fwimg_regions.h" -#include /* needed for memset */ - - -/** @addtogroup USER_APP User App Example - * @{ - */ - -/** @addtogroup SE_USER_CODE Secure Engine User Code Example - * @brief Example of user defined code running in Secure Engine. - * This code provides user defined services to the user application. - * @{ - */ - -/** @defgroup SE_USER_CODE_Private_Variables Private Variables - * @{ - */ -/** - * @} - */ - -/** @defgroup SE_USER_CODE_Private_Functions Private Functions - * @{ - */ - -/** - * @brief Display the SE_USER_CODE Menu choices on hyperterminal - * @param None. - * @retval None. - */ -static void SE_USER_CODE_PrintMenu(void) -{ - printf("\r\n=== Call User Defined Code running in Secure Engine ===\r\n\n"); - printf(" Get firmware information of SLOT_ACTIVE_1 ------------- 1\r\n\n"); - printf(" Previous Menu ----------------------------------------- x\r\n\n"); - printf(" Selection :\r\n\n"); -} - -/** - * @brief Get FW information. - * @param SlotNumber slot identification - * @retval HAL Status. - */ -static void SE_USER_CODE_GetFwInfo(uint32_t SlotNumber) -{ - SE_ErrorStatus se_retCode = SE_ERROR; - SE_StatusTypeDef se_Status = SE_KO; - SE_APP_ActiveFwInfo_t sl_FwInfo; - - memset(&sl_FwInfo, 0xFF, sizeof(SE_APP_ActiveFwInfo_t)); - - - - /* Get FW info */ - se_retCode = SE_APP_GetActiveFwInfo(&se_Status, SlotNumber, &sl_FwInfo); - - if ((SE_SUCCESS == se_retCode) && (SE_OK == se_Status)) - { - /* Print the result */ - printf("Firmware Info:\r\n"); - printf("\tActiveFwVersion: %d\r\n", sl_FwInfo.ActiveFwVersion); - printf("\tActiveFwSize: %d bytes\r\n", sl_FwInfo.ActiveFwSize); - } - else - { - /* Failure */ - printf(" -- !!Operation failed!! \r\n\n"); - } - -} - - -/** - * @} - */ - -/** @addtogroup SE_USER_CODE_Exported_Functions - * @{ - */ - -/** - * @brief Run get firmware info menu. - * @param None - * @retval HAL Status. - */ -void SE_USER_CODE_RunMenu(void) -{ - uint8_t key = 0U; - uint32_t exit = 0U; - uint32_t slot_number = 0U; - - /*Print Main Menu message*/ - SE_USER_CODE_PrintMenu(); - - while (exit == 0U) - { - key = 0U; - slot_number = 0U; - - /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload - register */ - WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); - - /* Clean the input path */ - COM_Flush(); - - /* Receive key */ - if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) - { - switch (key) - { - case '1' : - slot_number = SLOT_ACTIVE_1; - if (SlotStartAdd[slot_number] == 0U) - { - printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); - } - else - { - SE_USER_CODE_GetFwInfo(slot_number); - } - break; - case 'x' : - exit = 1U; - break; - default: - printf("Invalid Number !\r"); - break; - } - - /*Print Main Menu message*/ - SE_USER_CODE_PrintMenu(); - } - } -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/stm32wlxx_it.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/stm32wlxx_it.c deleted file mode 100644 index 899060b5..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/stm32wlxx_it.c +++ /dev/null @@ -1,210 +0,0 @@ -/** - ****************************************************************************** - * @file stm32wlxx_it.c - * @author MCD Application Team - * @brief Main Interrupt Service Routines. - * This file provides template for all exceptions handler and - * peripherals interrupt service routine. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "stm32wlxx_it.h" -#include "test_protections.h" - -/** @addtogroup USER_APP User App Example - * @{ - */ - -/** @addtogroup USER_APP_COMMON Common - * @{ - */ -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -RTC_HandleTypeDef RtcHandle; -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/******************************************************************************/ -/* Cortex-M4 Processor Exceptions Handlers */ -/******************************************************************************/ - -/** - * @brief This function handles NMI exception. - * @param None - * @retval None - */ -void NMI_Handler(void) -{ - /* Go to infinite loop when NMI exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Hard Fault exception. - * @param None - * @retval None - */ -void HardFault_Handler(void) -{ - /* Go to infinite loop when Memory Manage exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Memory Manage exception. - * @param None - * @retval None - */ -void MemManage_Handler(void) -{ - /* Go to infinite loop when Memory Manage exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Bus Fault exception. - * @param None - * @retval None - */ -void BusFault_Handler(void) -{ - /* Go to infinite loop when Bus Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles Usage Fault exception. - * @param None - * @retval None - */ -void UsageFault_Handler(void) -{ - /* Go to infinite loop when Usage Fault exception occurs */ - while (1) - { - } -} - -/** - * @brief This function handles SVCall exception. - * @param None - * @retval None - */ -void SVC_Handler(void) -{ -} - -/** - * @brief This function handles Debug Monitor exception. - * @param None - * @retval None - */ -void DebugMon_Handler(void) -{ -} - -/** - * @brief This function handles PendSVC exception. - * @param None - * @retval None - */ -void PendSV_Handler(void) -{ -} - -/** - * @brief This function handles SysTick Handler. - * @param None - * @retval None - */ -void SysTick_Handler(void) -{ - HAL_IncTick(); -} - -/******************************************************************************/ -/* STM32WLxx Peripherals Interrupt Handlers */ -/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ -/* available peripheral interrupt handler's name please refer to the startup */ -/* file (startup_stm32wlxx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles Flash operation error interrupt request. - * @param None - * @retval None - */ -void FLASH_IRQHandler(void) -{ - HAL_FLASH_IRQHandler(); -} - -/** - * @brief This function handles Tamper interrupt request. - * @param None - * @retval None - */ -void TAMP_STAMP_LSECSS_SSRU_IRQHandler() -{ - /* Store in the handle the Internal Tamper enabled */ - SET_BIT(RtcHandle.IsEnabled.TampFeatures, RTC_TAMPER_ID); - - RtcHandle.Instance = RTC; - HAL_RTCEx_TamperIRQHandler(&RtcHandle); -} - -void BUTTON_IRQHANDLER(void) -{ - HAL_GPIO_EXTI_IRQHandler(BUTTON_EXTI_LINE); -} - -void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) -{ - if (GPIO_Pin == BUTTON_EXTI_LINE) - { - printf("\r\nUser IRQ Handler: User Button pressed\r\n"); - } -} - -/** - * @brief This function handles PPP interrupt request. - * @param None - * @retval None - */ -/*void PPP_IRQHandler(void) -{ -}*/ - - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/test_protections.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/test_protections.c deleted file mode 100644 index a2491e4b..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/test_protections.c +++ /dev/null @@ -1,454 +0,0 @@ -/** - ****************************************************************************** - * @file test_protections.c - * @author MCD Application Team - * @brief Test Protections module. - * This file provides set of firmware functions to manage Test Protections - * functionalities. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -#define TEST_PROTECTIONS_C - -/* Includes ------------------------------------------------------------------*/ -#include -#include "test_protections.h" -#include "se_def.h" -#include "se_interface_application.h" -#include "com.h" -#include "common.h" -#include "flash_if.h" -#include "sfu_fwimg_regions.h" /* required for corruption tests (a real user application should NOT need this file) */ -#if defined(__ARMCC_VERSION) -#include "mapping_sbsfu.h" -#elif defined (__ICCARM__) || defined(__GNUC__) -#include "mapping_export.h" -#endif /* __ARMCC_VERSION */ -/** @addtogroup USER_APP User App Example - * @{ - */ - -/** @addtogroup TEST_PROTECTIONS Test protections - * @{ - */ - -/** @defgroup TEST_PROTECTIONS_Private_Defines Private Defines - * @{ - */ - -/** - * @brief Isolated enclave Test. - */ -/*!< Address used to test SE CODE protection*/ -#define TEST_PROTECTIONS_SE_ISOLATED_CODE_FLASH_ADDRESS ((uint32_t) SE_CALLGATE_REGION_ROM_START) -/*!< Address used to test SE VDATA protection*/ -#define TEST_PROTECTIONS_SE_ISOLATED_VDATA_SRAM_ADDRESS ((uint32_t) SE_REGION_RAM_START) - -/** - * @brief WRP Test. - */ -/*!< Address used to test WRP protection */ -#define TEST_PROTECTIONS_WRP_FLASH_ADDRESS ((uint32_t) (KMS_DATASTORAGE_START - 0x1000)) -/*!< WRP Test Size */ -#define TEST_PROTECTIONS_WRP_FLASH_SIZE ((uint32_t)0x800U) - -/** - * @brief IWDG Test. - */ -/*!< IWDG Test delay in ms (it has to be greater than what used in SB)*/ -#define TEST_PROTECTIONS_IWDG_DELAY ((uint32_t)10000U) - -/** - * @brief TAMPER Test. - */ -#define TEST_PROTECTIONS_TAMPER_DELAY ((uint32_t)10U) /*!< TAMPER Test delay in s */ - -/** - * @brief CORRUPT_IMAGE Test. - */ -/*!< CORRUPT_IMAGE Test: address where data will be corrupted: address of active slot + offset */ -#define TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(A) ((uint32_t)(SlotStartAdd[A] \ - +SFU_IMG_IMAGE_OFFSET)) -/*!< CORRUPT_IMAGE Test: size of data to be corrupted */ -#define TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE ((uint32_t)32U) - -/** @defgroup TEST_PROTECTIONS_Private_Variables Private Variables - * @{ - */ -static uint8_t uRead_WRP[TEST_PROTECTIONS_WRP_FLASH_SIZE]; /*!< RTC handler used for TAMPER Test */ -static uint32_t m_uTamperEvent = 0U; /*!< Tamper Event */ - -/** @defgroup TEST_PROTECTIONS_Private_Functions Private Functions - * @{ - */ -static void TEST_PROTECTIONS_RunWRP(void); -static void TEST_PROTECTIONS_RunTAMPER(void); -static void TEST_PROTECTIONS_RunIWDG(void); -static void TEST_PROTECTIONS_CORRUPT_RunMenu(void); -static void TEST_PROTECTIONS_PrintTestingMenu(void); -/** - * @} - */ - - - - -/** @defgroup TEST_PROTECTIONS_Exported_Functions Exported Functions - * @{ - */ - -/** @defgroup TEST_PROTECTIONS_Control_Functions Control Functions - * @{ - */ - -/** - * @brief Display the TEST Main Menu choices on HyperTerminal - * @param None. - * @retval None. - */ -void TEST_PROTECTIONS_RunMenu(void) -{ - uint8_t key = 0U; - uint8_t exit = 0U; - - /* Print Main Menu message */ - TEST_PROTECTIONS_PrintTestingMenu(); - - while (exit == 0U) - { - key = 0U; - - /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the - reload register*/ - WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); - - /* Clean the input path */ - COM_Flush(); - - /* Receive key */ - if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) - { - switch (key) - { - case '1' : - TEST_PROTECTIONS_CORRUPT_RunMenu(); - break; - case '2' : - TEST_PROTECTIONS_RunWRP(); - break; - case '3' : - TEST_PROTECTIONS_RunIWDG(); - break; - case '4' : - TEST_PROTECTIONS_RunTAMPER(); - break; - case 'x' : - exit = 1U; - break; - - default: - printf("Invalid Number !\r"); - break; - } - /*Print Main Menu message*/ - TEST_PROTECTIONS_PrintTestingMenu(); - } - } -} - - -/** - * @} - */ - -/** - * @} - */ - -/** @addtogroup TEST_PROTECTIONS_Private_Functions - * @{ - */ - -/** - * @brief Display the TEST Main Menu choices on HyperTerminal - * @param None. - * @retval None. - */ -static void TEST_PROTECTIONS_PrintTestingMenu(void) -{ - printf("\r\n=================== Test Menu ============================\r\n\n"); - printf(" Test : CORRUPT ACTIVE IMAGE --------------------------- 1\r\n\n"); - printf(" Test Protection: WRP ---------------------------------- 2\r\n\n"); - printf(" Test Protection: IWDG --------------------------------- 3\r\n\n"); - printf(" Test Protection: TAMPER ------------------------------- 4\r\n\n"); - printf(" Previous Menu ----------------------------------------- x\r\n\n"); - printf(" Selection :\r\n\n"); -} - - -/** - * @brief TEST Run WRP - * @param None. - * @retval None. - */ -static void TEST_PROTECTIONS_RunWRP(void) -{ - uint32_t i = 0U; - uint32_t address = 0U; - - printf("\r\n====== Test Protection: WRP ===========================\r\n\n"); - - address = TEST_PROTECTIONS_WRP_FLASH_ADDRESS; - - /* #1 - Read Page to be used for restoring*/ - printf(" -- Reading 0x%x bytes at address: 0x%x (for backup)\r\n\n", TEST_PROTECTIONS_WRP_FLASH_SIZE, - TEST_PROTECTIONS_WRP_FLASH_ADDRESS); - - for (i = 0U; i < TEST_PROTECTIONS_WRP_FLASH_SIZE; i++) - { - uRead_WRP[i] = *((uint8_t *)(address + i)); - } - - /* #2 - Erasing page */ - printf(" -- Erasing 0x%x bytes at address: 0x%x\r\n\n", TEST_PROTECTIONS_WRP_FLASH_SIZE, - TEST_PROTECTIONS_WRP_FLASH_ADDRESS); - - /* Check that it is not allowed to erase this page */ - if (FLASH_If_Erase_Size((void *)address, TEST_PROTECTIONS_WRP_FLASH_SIZE) != HAL_OK) - { - /* Error returned during programmation. */ - /* Check that WRPERR flag is set */ - if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) != 0U) - { - printf("-- !! HAL_FLASH_ERROR_WRP: FLASH Write protected error flag !!\r\n\n"); - } - } - else - { - /* #3 - Writing Data previously read*/ - if (FLASH_If_Write((void *)address, uRead_WRP, TEST_PROTECTIONS_WRP_FLASH_SIZE) != HAL_OK) - { - /* Error returned during programmation. */ - printf("-- !! HAL_FLASH_ERROR: FLASH Write error\r\n\n"); - - /* Check that WRPERR flag is set */ - if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) != 0U) - { - printf("-- !! HAL_FLASH_ERROR_WRP: FLASH Write protected error flag !!\r\n\n"); - } - } - else - { - printf(" -- Written successfully at address: 0x%x\r\n\n", TEST_PROTECTIONS_WRP_FLASH_ADDRESS); - - /*No Errors detected means WRP was not enabled*/ - printf(" -- !! WRP protection is NOT ENABLED !!\r\n\n"); - } - } -} - -/** - * @brief TEST Run CORRUPT_IMAGE - * @param None. - * @retval None. - */ -static void TEST_PROTECTIONS_RunCORRUPT(uint32_t slot_number) -{ - HAL_StatusTypeDef ret = HAL_ERROR; - uint8_t pattern[TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE] = {0}; - - /* On this series, there is no MPU to disable to allow flash corruption. */ - - /* Erase first sector of active slot */ - printf(" -- Erasing 0x%x bytes at address: 0x%x\r\n", TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE, - TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(slot_number)); - printf(" -- At next boot Signature Verification will fail. Download a new FW to restore FW image !!\r\n\n"); - - /* On this series, the memory corruption is performed by writing again the flash (but not header). - The header is preserved for anti-rollback check. */ - ret = FLASH_If_Write((void *)(TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(slot_number)), (void *) &pattern, - TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE); - - /* This code may not be reached, due to the memory corruption performed. - In this case, the execution will probably trig hard fault exception (while (1)), - then watchdog reset. */ - if (ret == HAL_OK) - { - NVIC_SystemReset(); - } - else - { - printf("-- !! HAL_FLASH_ERROR_CORRUPT_IMAGE: erasing failure ...\r\n\n"); - } -} - -/** - * @brief Display the corruption menu - * @param None. - * @retval None. - */ -static void TEST_PROTECTIONS_CORRUPT_PrintMenu(void) -{ - printf("\r\n============ Test: CORRUPT ACTIVE IMAGE ============\r\n\n"); - printf(" Corrupt image from SLOT_ACTIVE_1 ---------------------- 1\r\n\n"); - printf(" Selection :\r\n\n"); -} - -/** - * @brief Run get firmware info menu. - * @param None - * @retval HAL Status. - */ -static void TEST_PROTECTIONS_CORRUPT_RunMenu(void) -{ - uint8_t key = 0U; - uint32_t exit = 0U; - uint32_t slot_number = 0U; - - /*Print Main Menu message*/ - TEST_PROTECTIONS_CORRUPT_PrintMenu(); - - while (exit == 0U) - { - key = 0U; - slot_number = 0U; - - /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload - register */ - WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); - - /* Clean the input path */ - COM_Flush(); - - /* Receive key */ - if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) - { - switch (key) - { - case '1' : - slot_number = SLOT_ACTIVE_1; - break; - case 'x' : - exit = 1U; - break; - default: - printf("Invalid Number !\r"); - break; - } - - if (SlotStartAdd[slot_number] == 0U) - { - printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); - } - else - { - TEST_PROTECTIONS_RunCORRUPT(slot_number); - } - - /*Print Main Menu message*/ - TEST_PROTECTIONS_CORRUPT_PrintMenu(); - } - } -} - - -/** - * @brief TEST Run TAMPER - * @param None. - * @retval None. - */ -static void TEST_PROTECTIONS_RunTAMPER(void) -{ - uint32_t i = 0U; - m_uTamperEvent = 0U; - - printf("\r\n====== Test Protection: TAMPER ========================\r\n\n"); - /* Print instructions*/ - printf(" -- Pull PC13 (CN7.23) to GND \r\n\n"); - printf(" -- -- Note: sometimes it may be enough to put your finger close to PC13 (CN7.23)\r\n\n"); - printf(" -- Should reset if TAMPER is enabled. \r\n\n"); - printf(" Waiting for 10 seconds...\r\n\n") ; - - /* #2 - Wait 10 seconds*/ - while ((i < TEST_PROTECTIONS_TAMPER_DELAY) && (m_uTamperEvent == 0U)) - { - /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload register - */ - WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); - HAL_Delay(1000U); - i++; - } - if (m_uTamperEvent == 0U) - { - printf("\r\n\n -- Waited 10 seconds, if you have connected TAMPER pin to GND it means TAMPER protection "); - printf("is NOT ENABLED !! \r\n\n"); - } - else - { - printf("\r\n\n -- TAMPER Event detected!!\r\n\n -- System reset requested!!!\r\n\n"); - NVIC_SystemReset(); - } -} - -/** - * @brief TEST Run IWDG - * @param None. - * @retval None. - */ -static void TEST_PROTECTIONS_RunIWDG(void) -{ - printf("\r\n====== Test Protection: IWDG ===========================\r\n\n"); - - /* Wait for TEST_PROTECTIONS_IWDG_DELAY*/ - printf(" -- Waiting %d (ms). Should reset if IWDG is enabled. \r\n\n", TEST_PROTECTIONS_IWDG_DELAY); - - HAL_Delay(TEST_PROTECTIONS_IWDG_DELAY); - - /* No Reset means IWDG was not enabled*/ - printf(" -- !! IWDG protection is NOT ENABLED !!\r\n\n"); -} - -/** - * @} - */ - -/** @defgroup TEST_PROTECTIONS_Callback_Functions Callback Functions - * @{ - */ - -/** - * @brief Implement the Cube_Hal Callback generated on the Tamper IRQ. - * @param None - * @retval None - */ -void CALLBACK_Antitamper(void) -{ - /*Set tamper event variable*/ - m_uTamperEvent = 1U; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app.c deleted file mode 100644 index f97b7f89..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app.c +++ /dev/null @@ -1,183 +0,0 @@ -/** - ****************************************************************************** - * @file tkms_app.c - * @author MCD Application Team - * @brief tKMS application examples module. - * This file provides examples of KMS API usages. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "tkms.h" -#include "tkms_app.h" -#include "com.h" -#include "common.h" - - -/* Private variables ---------------------------------------------------------*/ -extern void KMS_UPDATE_StartLocalUpdate(void); - -static void tkms_app_print_menu(void) -{ - (void)printf("\r\n======================= tKMS Examples Menu ===========================\r\n\n"); - (void)printf(" (*) Requires execution of 'Import Blob' test (3) prior to execute this one\r\n\n"); - (void)printf(" TKMS - Test All (*) --------------------- 0\r\n\n"); - (void)printf(" TKMS - Tests AES-GCM Embedded key --------------------- 1\r\n\n"); - (void)printf(" TKMS - Tests AES-CBC Embedded key --------------------- 2\r\n\n"); - (void)printf(" TKMS - Import blob --------------------- 3\r\n\n"); - (void)printf(" TKMS - Tests RSA Static key (*) --------------------- 4\r\n\n"); - (void)printf(" TKMS - Tests Derive Static key (*) --------------------- 5\r\n\n"); - (void)printf(" Exit tKMS Examples Menu --------------------- x\r\n\n"); -} - -void tkms_app_menu(void) -{ - uint8_t key; - uint8_t exit = 0U; - CK_RV ret_status; - uint8_t tests_executed; - uint8_t tests_success; - uint8_t clear_buffer[128] = "STM32 Key Management Services - Example buffer"; - - /* Initialize tKMS for subsequent usage */ - ret_status = C_Initialize(NULL); - if (ret_status != CKR_OK) - { - (void)printf("tKMS initialization failed\r\n"); - exit = 1; - } - else - { - tkms_app_print_menu(); - } - - while (exit == 0U) - { - key = 0U; - - INVOKE_SCHEDULE_NEEDS(); - - /* Clean the user input path */ - (void)COM_Flush(); - - /* Receive key */ - if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) - { - switch (key) - { - case '0' : - tests_executed = 0U; - tests_success = 0U; - ret_status = tkms_app_encrypt_decrypt_aes_gcm(sizeof(clear_buffer), clear_buffer); - (void)printf("AES GCM test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tests_executed++; - tests_success += (ret_status == CKR_OK) ? 1U : 0U; - INVOKE_SCHEDULE_NEEDS(); - ret_status = tkms_app_encrypt_decrypt_aes_cbc(sizeof(clear_buffer), clear_buffer); - (void)printf("AES CBC test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tests_executed++; - tests_success += (ret_status == CKR_OK) ? 1U : 0U; - INVOKE_SCHEDULE_NEEDS(); - ret_status = tkms_app_sign_verify_rsa(sizeof(clear_buffer), clear_buffer); - (void)printf("RSA test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tests_executed++; - tests_success += (ret_status == CKR_OK) ? 1U : 0U; - INVOKE_SCHEDULE_NEEDS(); - ret_status = tkms_app_derive_key(sizeof(clear_buffer), clear_buffer); - (void)printf("Derive key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tests_executed++; - tests_success += (ret_status == CKR_OK) ? 1U : 0U; - INVOKE_SCHEDULE_NEEDS(); - if (tests_success == tests_executed) - { - (void)printf("CUMULATIVE RESULT: ALL TESTS PASSED\r\n"); - } - else - { - (void)printf("CUMULATIVE RESULT: %d/%d success\r\n", tests_success, tests_executed); - } - tkms_app_print_menu(); - break; - - /* 1 = TKMS - Tests AES-GCM Embedded key */ - case '1' : - INVOKE_SCHEDULE_NEEDS(); - ret_status = tkms_app_encrypt_decrypt_aes_gcm(sizeof(clear_buffer), clear_buffer); - (void)printf("AES GCM test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tkms_app_print_menu(); - break; - /* 2 = Tests AES-CBC Embedded key */ - case '2' : - INVOKE_SCHEDULE_NEEDS(); - ret_status = tkms_app_encrypt_decrypt_aes_cbc(sizeof(clear_buffer), clear_buffer); - (void)printf("AES CBC test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tkms_app_print_menu(); - break; - /* 3 = Import Blob */ - case '3': - INVOKE_SCHEDULE_NEEDS(); - KMS_UPDATE_StartLocalUpdate(); - tkms_app_print_menu(); - break; - /* 4 = Tests RSA Static key (requires blob import) */ - case '4' : - INVOKE_SCHEDULE_NEEDS(); - ret_status = tkms_app_sign_verify_rsa(sizeof(clear_buffer), clear_buffer); - (void)printf("RSA test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tkms_app_print_menu(); - break; - /* 5 = Tests Key derivation (requires blob import) */ - case '5': - INVOKE_SCHEDULE_NEEDS(); - ret_status = tkms_app_derive_key(sizeof(clear_buffer), clear_buffer); - (void)printf("Derive key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); - tkms_app_print_menu(); - break; - case 'x': - exit = 1; - break; - - default: - (void)printf("Invalid Number !\r"); - tkms_app_print_menu(); - break; - } - } - } - - /* Finalize tKMS since no more in use */ - ret_status = C_Finalize(NULL); - if (ret_status != CKR_OK) - { - (void)printf("tKMS finalization failed\r\n"); - } -} - -void tkms_buff2str(uint8_t *pbuff, uint8_t *pstr, uint32_t length) -{ - uint8_t ascii[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - uint8_t *ptmp = pstr; - uint8_t *ptmp2 = pbuff; - for (uint32_t i = 0UL; i < length; i += 1UL) - { - *ptmp = ascii[*ptmp2 >> 4]; - ptmp++; - *ptmp = ascii[*ptmp2 & 0x0FUL]; - ptmp++; - ptmp2++; - } - *ptmp = 0U; -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_derive_key.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_derive_key.c deleted file mode 100644 index bd2e720f..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_derive_key.c +++ /dev/null @@ -1,205 +0,0 @@ -/** - ****************************************************************************** - * @file tkms_app_derive_key.c - * @author MCD Application Team - * @brief tKMS application examples module. - * This file provides examples of KMS API usage to derivate a key - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "tkms.h" -#include "tkms_app.h" -#include "com.h" -#include "common.h" -#include "kms_platf_objects_interface.h" - -/* Private defines -----------------------------------------------------------*/ -#define EC_POINT_MAX_LEN (3U + (2U * 32U)) /* EC Point Max Length : X962 header + DER header + - NIST-P256 *2 - > (0x04|LEN|0x04|X|Y) */ -#define DH_SECRET_X_MAX_LEN (32U) /* DH Secret X Max Length */ - -/* Private structures -- -----------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -static uint8_t a_string[1024] = {0}; - -/* - * Key derivation - * ----------------------------------------------------------------------------- - * This example is showing how to use key derivation to create - * a specific session key. - * ----------------------------------------------------------------------------- - * Key derivation shared information between emitter and receiver - * - Secret derivation Key: stored in KMS under - * KMS_KEY_AES128_DERIVABLE_OBJECT_HANDLE object handle - * - Session key variation: transmitted or calculated by both emitter & receiver - */ -CK_RV tkms_app_derive_key(uint32_t length, uint8_t *pClearMessage) -{ - uint8_t encrypted_message[256] __attribute__((aligned(8))) = {0}; - uint8_t decrypted_message[256] __attribute__((aligned(8))) = {0}; - CK_ULONG DeriveKey_template_class = CKO_SECRET_KEY; - CK_ULONG DeriveKey_template_destroyable = CK_TRUE; - CK_ULONG DeriveKey_template_encrypt = CK_TRUE; - CK_ULONG DeriveKey_template_decrypt = CK_TRUE; - CK_ULONG DeriveKey_template_extract = CK_TRUE; - CK_ATTRIBUTE DeriveKey_template[] = - { - {CKA_CLASS, (CK_VOID_PTR) &DeriveKey_template_class, sizeof(CK_ULONG)}, - {CKA_DESTROYABLE, (CK_VOID_PTR) &DeriveKey_template_destroyable, sizeof(CK_ULONG)}, - {CKA_ENCRYPT, (CK_VOID_PTR) &DeriveKey_template_encrypt, sizeof(CK_ULONG)}, - {CKA_DECRYPT, (CK_VOID_PTR) &DeriveKey_template_decrypt, sizeof(CK_ULONG)}, - {CKA_EXTRACTABLE, (CK_VOID_PTR) &DeriveKey_template_extract, sizeof(CK_ULONG)} - }; - CK_ATTRIBUTE GetKey_template[] = {{CKA_VALUE, (CK_VOID_PTR) &DeriveKey_template_class, 32UL}}; - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - /* Key derivation */ - uint8_t session_variant[32] = "My session variation 0122004578"; - CK_MECHANISM mech = {CKM_AES_ECB_ENCRYPT_DATA, session_variant, 32}; - CK_OBJECT_HANDLE derivedKeyHdle = 0UL; - uint8_t derivedKey[32] = {0}; - /* AES encryption / decryption */ - uint32_t encrypted_length = 0UL; - uint32_t decrypted_length = 0UL; - uint8_t cbc_iv[16] = ">CBC VECTOR "; - CK_MECHANISM aes_cbc_mechanism = { CKM_AES_CBC, (CK_VOID_PTR)cbc_iv, sizeof(cbc_iv) }; - uint8_t tag[16] = {0}; - uint32_t tag_lenth; - - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); - - /* Derive key with pass phrase */ - if (rv == CKR_OK) - { - rv = C_DeriveKey(session, &(mech), (CK_OBJECT_HANDLE)KMS_KEY_AES128_DERIVABLE_OBJECT_HANDLE, - &DeriveKey_template[0], sizeof(DeriveKey_template) / sizeof(CK_ATTRIBUTE), &derivedKeyHdle); - } - - /* Get derived key to display */ - if (rv == CKR_OK) - { - GetKey_template[0].pValue = derivedKey; - rv = C_GetAttributeValue(session, derivedKeyHdle, &(GetKey_template[0]), sizeof(GetKey_template) / - sizeof(CK_ATTRIBUTE)); - } - if (rv == CKR_OK) - { - (void)printf("--- Derivating key --------------------------------------------\r\n"); - (void)printf("--- AES ECB\r\n"); - (void)printf("--- Pass phrase [%s]\r\n", session_variant); - tkms_buff2str(derivedKey, a_string, 32); - (void)printf("--- Derived key [%s]\r\n", a_string); - } - - /* Encryption --------------------------------------------------------------*/ - (void)printf("--- Encrypting --------------------------------------------------\r\n"); - (void)printf("--- AES CBC\r\n"); - (void)printf("--- IV [%s]\r\n", cbc_iv); - (void)printf("--- Message [%s]\r\n", pClearMessage); - tkms_buff2str(pClearMessage, a_string, length); - (void)printf("--- [0x%s]\r\n", a_string); - (void)printf("--- Length [%d]\r\n", length); - - /* Configure session to encrypt message in AES GCM with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_EncryptInit(session, &aes_cbc_mechanism, derivedKeyHdle); - } - - /* Encrypt clear message */ - if (rv == CKR_OK) - { - encrypted_length = sizeof(encrypted_message); - rv = C_EncryptUpdate(session, pClearMessage, length, - encrypted_message, &encrypted_length); - } - - /* Finalize message encryption */ - if (rv == CKR_OK) - { - tag_lenth = sizeof(tag); - rv = C_EncryptFinal(session, &tag[0], &tag_lenth); - } - - (void)printf("--- Encrypted ---------------------------------------------------\r\n"); - tkms_buff2str(encrypted_message, a_string, encrypted_length); - (void)printf("--- Message [0x%s]\r\n", a_string); - - /* Decryption --------------------------------------------------------------*/ - - /* Configure session to decrypt message in AES GCM with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_DecryptInit(session, &aes_cbc_mechanism, derivedKeyHdle); - } - - /* Decrypt encrypted message */ - if (rv == CKR_OK) - { - decrypted_length = sizeof(decrypted_message); - rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, - decrypted_message, &decrypted_length); - } - - /* Finalize message decryption */ - if (rv == CKR_OK) - { - tag_lenth = sizeof(tag); - rv = C_DecryptFinal(session, &tag[0], &tag_lenth); - } - (void)printf("--- Decrypted ---------------------------------------------------\r\n"); - (void)printf("--- Message [%s]\r\n", decrypted_message); - tkms_buff2str(decrypted_message, a_string, decrypted_length); - (void)printf("--- [0x%s]\r\n", a_string); - - /* Compare decrypted message with clear one */ - if (rv == CKR_OK) - { - if (memcmp(pClearMessage, decrypted_message, length) != 0) - { - (void)printf("XXX Decrypted message differs\r\n"); - rv = CKR_FUNCTION_FAILED; - } - else - { - (void)printf(">>> Decrypted message is same\r\n"); - } - } - - /* Remove key once no more needed */ - if (rv == CKR_OK) - { - rv = C_DestroyObject(session, derivedKeyHdle); - } - - /* Verify key is no more usable */ - if (rv == CKR_OK) - { - if (C_EncryptInit(session, &aes_cbc_mechanism, derivedKeyHdle) == CKR_OK) - { - rv = CKR_FUNCTION_FAILED; - } - } - - /* Close sessions */ - (void)C_CloseSession(session); - - return rv; -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c deleted file mode 100644 index 5401f895..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c +++ /dev/null @@ -1,280 +0,0 @@ -/** - ****************************************************************************** - * @file tkms_app_encrypt_decrypt.c - * @author MCD Application Team - * @brief KMS application examples module. - * This file provides examples of KMS API usage to encrypt & decrypt - * messages. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "tkms.h" -#include "tkms_app.h" -#include "com.h" -#include "common.h" -#include "kms_platf_objects_interface.h" - -/* Private defines ---------------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -static uint8_t a_string[1024] = {0}; -static uint8_t encrypted_message[256] __attribute__((aligned(8))) = {0}; -static uint8_t decrypted_message[256] __attribute__((aligned(8))) = {0}; - -/* - * AES GCM 128 Bits - * ----------------------------------------------------------------------------- - * This example is showing how to use AES GCM encryption/decryption to - * authenticate and protect a message. - * ----------------------------------------------------------------------------- - * Shared information between emitter and receiver - * - Secret encryption/decryption Key: stored in KMS under - * KMS_KEY_AES128_OBJECT_HANDLE object handle - * - Encrypted message: transmitted from emitter to sender - * - Initialization Vector: transmitted from emitter to sender - * - Message Header: transmitted from emitter to sender - * - Authentication Tag: transmitted from emitter to sender - * (calculated during encryption, verified during decryption) - */ -CK_RV tkms_app_encrypt_decrypt_aes_gcm(uint32_t length, uint8_t *pClearMessage) -{ - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - uint32_t encrypted_length = 0UL; - uint32_t decrypted_length = 0UL; - uint8_t tag[16] = {0}; /* 128 bits tag size */ - uint32_t tag_lenth = 0UL; - - /* AES GCM Configuration variables */ - uint8_t gcm_iv[12] = ">GCM VECTOR"; - uint8_t gcm_header[16] = ">AES GCM Header"; - CK_GCM_PARAMS gcm_params = - { - (CK_BYTE *)gcm_iv, - sizeof(gcm_iv), - (CK_BYTE_PTR)gcm_header, - sizeof(gcm_header), - 128 /* Tag length in Bits */ - }; - CK_MECHANISM aes_gcm_mechanism = { CKM_AES_GCM, (CK_VOID_PTR *)(uint32_t)&gcm_params, sizeof(gcm_params) }; - - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); - - /* Encryption --------------------------------------------------------------*/ - (void)printf("--- Encrypting --------------------------------------------------\r\n"); - (void)printf("--- AES GCM\r\n"); - (void)printf("--- IV [%s]\r\n", gcm_iv); - (void)printf("--- Header [%s]\r\n", gcm_header); - (void)printf("--- Message [%s]\r\n", pClearMessage); - tkms_buff2str(pClearMessage, a_string, length); - (void)printf("--- [0x%s]\r\n", a_string); - (void)printf("--- Length [%d]\r\n", length); - - /* Configure session to encrypt message in AES GCM with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_EncryptInit(session, &aes_gcm_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES128_OBJECT_HANDLE); - } - - /* Encrypt clear message */ - if (rv == CKR_OK) - { - encrypted_length = sizeof(encrypted_message); - rv = C_EncryptUpdate(session, pClearMessage, length, - encrypted_message, &encrypted_length); - } - - /* Finalize message encryption */ - if (rv == CKR_OK) - { - tag_lenth = sizeof(tag); - rv = C_EncryptFinal(session, &tag[0], &tag_lenth); - } - - (void)printf("--- Encrypted ---------------------------------------------------\r\n"); - tkms_buff2str(encrypted_message, a_string, encrypted_length); - (void)printf("--- Message [0x%s]\r\n", a_string); - tkms_buff2str(tag, a_string, tag_lenth); - (void)printf("--- Tag [0x%s]\r\n", a_string); - - /* Decryption --------------------------------------------------------------*/ - - /* Configure session to decrypt message in AES GCM with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_DecryptInit(session, &aes_gcm_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES128_OBJECT_HANDLE); - } - - /* Decrypt encrypted message */ - if (rv == CKR_OK) - { - decrypted_length = sizeof(decrypted_message); - rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, - decrypted_message, &decrypted_length); - } - - /* Finalize message decryption */ - if (rv == CKR_OK) - { - tag_lenth = sizeof(tag); - rv = C_DecryptFinal(session, &tag[0], &tag_lenth); - } - (void)printf("--- Decrypted ---------------------------------------------------\r\n"); - (void)printf("--- Message [%s]\r\n", decrypted_message); - tkms_buff2str(decrypted_message, a_string, decrypted_length); - (void)printf("--- [0x%s]\r\n", a_string); - - if (rv == CKR_OK) - { - (void)printf(">>> Decrypted message authenticated\r\n"); - } - else - { - (void)printf("XXX Decrypted message not authenticated\r\n"); - } - - /* Compare decrypted message with clear one */ - if (rv == CKR_OK) - { - if (memcmp(pClearMessage, decrypted_message, length) != 0) - { - (void)printf("XXX Decrypted message differs\r\n"); - rv = CKR_FUNCTION_FAILED; - } - else - { - (void)printf(">>> Decrypted message is same\r\n"); - } - } - - /* Close session with KMS */ - (void)C_CloseSession(session); - - return rv; -} - -/* - * AES CBC 256 Bits - * ----------------------------------------------------------------------------- - * This example is showing how to use AES CBC encryption/decryption to - * protect a message. - * ----------------------------------------------------------------------------- - * CBC shared information between emitter and receiver - * - Secret encryption/decryption Key: stored in KMS under - * KMS_KEY_AESC256_OBJECT_HANDLE object handle - * - Encrypted message: transmitted from emitter to sender - * - Initialization Vector: transmitted from emitter to sender - */ -CK_RV tkms_app_encrypt_decrypt_aes_cbc(uint32_t length, uint8_t *pClearMessage) -{ - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - uint32_t encrypted_length = 0UL; - uint32_t decrypted_length = 0UL; - uint8_t tag[16] = {0}; - uint32_t tag_lenth; - - /* AES CBC Configuration variables */ - uint8_t cbc_iv[16] = ">CBC VECTOR "; - CK_MECHANISM aes_cbc_mechanism = { CKM_AES_CBC, (CK_VOID_PTR)(uint32_t)cbc_iv, sizeof(cbc_iv) }; - - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); - - /* Encryption --------------------------------------------------------------*/ - (void)printf("--- Encrypting --------------------------------------------------\r\n"); - (void)printf("--- AES CBC\r\n"); - (void)printf("--- IV [%s]\r\n", cbc_iv); - (void)printf("--- Message [%s]\r\n", pClearMessage); - tkms_buff2str(pClearMessage, a_string, length); - (void)printf("--- [0x%s]\r\n", a_string); - (void)printf("--- Length [%d]\r\n", length); - - /* Configure session to encrypt message in AES CBC with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_EncryptInit(session, &aes_cbc_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES256_OBJECT_HANDLE); - } - - /* Encrypt clear message */ - if (rv == CKR_OK) - { - encrypted_length = sizeof(encrypted_message); - rv = C_EncryptUpdate(session, pClearMessage, length, - encrypted_message, &encrypted_length); - } - - /* Finalize message encryption */ - if (rv == CKR_OK) - { - tag_lenth = sizeof(tag); - rv = C_EncryptFinal(session, &tag[0], &tag_lenth); - } - - (void)printf("--- Encrypted ---------------------------------------------------\r\n"); - tkms_buff2str(encrypted_message, a_string, encrypted_length); - (void)printf("--- Message [0x%s]\r\n", a_string); - - /* Decryption --------------------------------------------------------------*/ - - /* Configure session to decrypt message in AES CBC with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_DecryptInit(session, &aes_cbc_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES256_OBJECT_HANDLE); - } - - /* Decrypt encrypted message */ - if (rv == CKR_OK) - { - decrypted_length = sizeof(decrypted_message); - rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, - decrypted_message, &decrypted_length); - } - - /* Finalize message decryption */ - if (rv == CKR_OK) - { - tag_lenth = sizeof(tag); - rv = C_DecryptFinal(session, &tag[0], &tag_lenth); - } - (void)printf("--- Decrypted ---------------------------------------------------\r\n"); - (void)printf("--- Message [%s]\r\n", decrypted_message); - tkms_buff2str(decrypted_message, a_string, decrypted_length); - (void)printf("--- [0x%s]\r\n", a_string); - - /* Compare decrypted message with clear one */ - if (rv == CKR_OK) - { - if (memcmp(pClearMessage, decrypted_message, length) != 0) - { - (void)printf("XXX Decrypted message differs\r\n"); - rv = CKR_FUNCTION_FAILED; - } - else - { - (void)printf(">>> Decrypted message is same\r\n"); - } - } - - /* Close session with KMS */ - (void)C_CloseSession(session); - - return rv; -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_sign_verify.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_sign_verify.c deleted file mode 100644 index cd6b1209..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/tkms_app_sign_verify.c +++ /dev/null @@ -1,119 +0,0 @@ -/** - ****************************************************************************** - * @file tkms_app_sign_verify.c - * @author MCD Application Team - * @brief KMS application examples module. - * This file provides examples of KMS API usage to sign & verify - * messages. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "tkms.h" -#include "tkms_app.h" -#include "com.h" -#include "common.h" -#include "kms_platf_objects_interface.h" - -/* Private defines -----------------------------------------------------------*/ - -/* Private variables ---------------------------------------------------------*/ -static uint8_t a_string[1024] = {0}; -static uint8_t signature[2048 / 8] __attribute__((aligned(8))) = {0}; - -/* - * RSA 1024 Bits - * ----------------------------------------------------------------------------- - * This example is showing how to use RSA signature to - * authenticate a message. - * ----------------------------------------------------------------------------- - * RSA shared information between emitter and receiver - * - Secret signature/verification Key: stored in KMS under - * KMS_KEY_RSA2048_OBJECT_HANDLE object handle - * - Message to authenticate: transmitted from emitter to sender - * - Signature: transmitted from emitter to sender - * (calculated by emitter, verified by receiver) - */ -CK_RV tkms_app_sign_verify_rsa(uint32_t length, uint8_t *pMessage) -{ - - CK_RV rv; - CK_SESSION_HANDLE session; - CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ - uint32_t signature_length = 0UL; - - CK_MECHANISM rsa_mechanism = { CKM_SHA256_RSA_PKCS, (CK_VOID_PTR *) NULL, 0}; - - /* Open session with KMS */ - rv = C_OpenSession(0, session_flags, NULL, 0, &session); - - /* Signature --------------------------------------------------------------*/ - (void)printf("--- Signing -----------------------------------------------------\r\n"); - (void)printf("--- RSA 1024 bits\r\n"); - (void)printf("--- Message [%s]\r\n", pMessage); - tkms_buff2str(pMessage, a_string, length); - (void)printf("--- [0x%s]\r\n", a_string); - (void)printf("--- Length [%d]\r\n", length); - - /* Configure session to sign message using RSA with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_SignInit(session, &rsa_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_RSA2048_OBJECT_HANDLE); - } - - /* Sign message */ - if (rv == CKR_OK) - { - signature_length = sizeof(signature); - rv = C_Sign(session, pMessage, length, - signature, &signature_length); - } - - (void)printf("--- Signed ------------------------------------------------------\r\n"); - tkms_buff2str(signature, a_string, signature_length); - (void)printf("--- Signature [0x%s]\r\n", a_string); - (void)printf("--- Length [%d]\r\n", signature_length); - - /* Verification ------------------------------------------------------------*/ - - /* Configure session to verify message using RSA with settings included into the mechanism */ - if (rv == CKR_OK) - { - rv = C_VerifyInit(session, &rsa_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_RSA2048_OBJECT_HANDLE); - } - - /* Verify message */ - if (rv == CKR_OK) - { - rv = C_Verify(session, pMessage, length, - signature, signature_length); - } - - if (rv == CKR_OK) - { - (void)printf(">>> Message authenticated\r\n"); - } - else - { - (void)printf("XXX Message not authenticated\r\n"); - } - - /* Close session with KMS */ - (void)C_CloseSession(session); - - return rv; -} - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/readme.txt deleted file mode 100644 index 8223627c..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/readme.txt +++ /dev/null @@ -1,136 +0,0 @@ -/** - @page 1_Image_UserApp / Firmware Update - User Application Demo - - @verbatim - ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* - * @file readme.txt - * @brief This application shows a User Application - ****************************************************************************** - * - * Copyright (c) 2017 STMicroelectronics. All rights reserved. - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - @endverbatim - -@par Application Description - -This application demonstrates firmware download capabilities and provides a set -of functions to test the active protections offered by Secure Boot and Secure Engine. -It also demonstrates key management services through basic examples and specific boot -mechanism (firmware update decryption, verification...) -A terminal connected with the board via VCOM is needed to communicate with the -board and to select which feature to demonstrate. - -For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" -available from the STMicroelectronics microcontroller website www.st.com. - -@par Keywords - -Security, KMS, SBSFU - -@par Directory contents - - - 1_Image_UserApp/Src/com.c Communication module file - - 1_Image_UserApp/Src/common.c Common module file - - 1_Image_UserApp/Src/flash_if.c Flash interface file - - 1_Image_UserApp/Src/fw_update_app.c Firmware update application - - 1_Image_UserApp/Src/kms_object_update_app.c KMS Blob update application - - 1_Image_UserApp/Src/main.c Main program - - 1_Image_UserApp/Src/se_user_code.c Call user defined services running in Secure Engine - - 1_Image_UserApp/Src/stm32wlxx_it.c Interrupt handlers - - 1_Image_UserApp/Src/system_stm32wlxx.c STM32 system file - - 1_Image_UserApp/Src/test_protections.c Protection test - - 1_Image_UserApp/Src/tkms_app.c tKMS tests - - 1_Image_UserApp/Src/tkms_app_derive_key.c tKMS key derivation tests - - 1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c tKMS encryption/decryption tests - - 1_Image_UserApp/Src/tkms_app_sign_verify.c tKMS signature/verification tests - - 1_Image_UserApp/Src/ymodem.c Ymodem communication module - - 1_Image_UserApp/Inc/com.h Header for com.c file - - 1_Image_UserApp/Inc/common.h Header for common.c file - - 1_Image_UserApp/Inc/flash_if.h Header for flash_if.c file - - 1_Image_UserApp/Inc/fw_update_app.h Header for fw_update_app.c file - - 1_Image_UserApp/Inc/main.h Header for main.c file - - 1_Image_UserApp/Inc/se_user_code.h Header file for se_user_code.c - - 1_Image_UserApp/Inc/sfu_app_new_image.h Definition for the new blob storage and installation - - 1_Image_UserApp/Inc/stm32wlxx_hal_conf.h HAL configuration file - - 1_Image_UserApp/Inc/stm32wlxx_it.h Header for stm32wlxx_it.c file - - 1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h BSP configuration file - - 1_Image_UserApp/Inc/test_protections.h Header for test_protections.c file - - 1_Image_UserApp/Inc/tkms_app.h Header for tkms_app.c file - - 1_Image_UserApp/Inc/ymodem.h Header for ymodem.c file - -@par Hardware and Software environment - - - This example runs on STM32WL55xx devices. - - This example has been tested with NUCLEO-WL55JC RevC board and can be - easily tailored to any other supported device and development board. - - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware - is a feature provided by STM32Cube programmer available on www.st.com. - - This example is based on se_interface_application.o module exported by BFU project. - - This example needs a terminal emulator. - - Microsoft Windows has a limitation whereby paths to files and directories cannot - be longer than 256 characters. Paths to files exceeding that limits cause tools (e.g. compilers, - shell scripts) to fail reading from or writing to such files. - As a workaround, it is advised to use the subst.exe command from within a command prompt to set - up a local drive out of an existing directory on the hard drive, such as: - C:\> subst X: \Firmware - -@par IDE postbuild script - -In order to ease the development process, a postbuild script ("postbuild.bat") is integrated in each IDE project. -This postbuild script: - - is generated when compiling the Secure Engine Core project, - - prepares the firmware image of the user application to be installed in the device. - -A known limitation of this integration occurs when you update the firmware version (parameter of -postbuild.bat script). -The IDE does not track this update so you need to force the rebuild of the project manually. - -@par How to use it ? - -Refer to BFU readme and follow steps by steps instructions. - -Once executed, this user application gives access to a menu which allows: - 1 - to download a new firmware : feature not supported in 1 firmware image example - 2 - to test protections (WRP, IWDG, TAMPER) - 3 - to demonstrate how to call user defined services running in Secure Engine - 4 - to provide access to multiple images feature (not supported) - 5 - to validate a firmware image at first start-up (not supported) - a - to demonstrate usage of key management services - -1. Pressing 1 allows to download a new firmware. - -Feature not supported in 1 firmware image example - -2. Pressing 2 allows to test protections. - - - CORRUPT IMAGE test (#1): causes a signature verification failure at next boot - - WRP test (#2): causes an error trying to erase write protected code - - IWDG test (#3): causes a reset simulating a deadlock by not refreshing the watchdog - - TAMPER test (#4): causes a reset if a tamper event is detected. In order to generate a tamper event, - user has to connect PC13 (CN7.23) to GND (It may be enough to put your finger close to PC13 (CN7.23)). - -Return to previous menu by pressing x. - -3. Pressing 3 allows to call user defined services running in Secure Engine. -As an example, SE_APP_GetActiveFwInfo service is called in order to display the firmware information -located in the protected area such as version and size. - -4. This menu is dedicated to multiple images feature. -Feature not available as there is only 1 download area configured. - -5. This menu is dedicated to image validation. -Feature available under ENABLE_IMAGE_STATE_HANDLING compilation switch, not available in this example. - -a. Pressing a allows to enter specific key management services test menu. -With this menu, you should be able to try encryption/decryption, signature/verification or key derivation mechanisms. - - -Note : for Linux users Minicom can be used but to do so you need to compile the UserApp project with the MINICOM_YMODEM switch enabled (ymodem.h) - *

      © COPYRIGHT STMicroelectronics

      - */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_export.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_export.h deleted file mode 100644 index 11c619fa..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_export.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - ****************************************************************************** - * @file mapping_export.h - * @author MCD Application Team - * @brief This file contains the definitions exported from mapping linker files. - ****************************************************************************** - * @attention - * - *

      © Copyright (c) 2017 STMicroelectronics. - * All rights reserved.

      - * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef MAPPING_EXPORT_H -#define MAPPING_EXPORT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Exported constants --------------------------------------------------------*/ -extern uint32_t __ICFEDIT_intvec_start__; -#define INTVECT_START ((uint32_t)& __ICFEDIT_intvec_start__) -extern uint32_t __ICFEDIT_SE_Startup_region_ROM_start__; -#define SE_STARTUP_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Startup_region_ROM_start__) -extern uint32_t __ICFEDIT_SE_Code_region_ROM_start__; -#define SE_CODE_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Code_region_ROM_start__) -extern uint32_t __ICFEDIT_SE_Code_region_ROM_end__; -#define SE_CODE_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_Code_region_ROM_end__) -extern uint32_t __ICFEDIT_SE_IF_region_ROM_start__; -#define SE_IF_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_IF_region_ROM_start__) -extern uint32_t __ICFEDIT_SE_IF_region_ROM_end__; -#define SE_IF_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_IF_region_ROM_end__) -extern uint32_t __ICFEDIT_SE_Key_region_ROM_start__; -#define SE_KEY_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Key_region_ROM_start__) -extern uint32_t __ICFEDIT_SE_Key_region_ROM_end__; -#define SE_KEY_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_Key_region_ROM_end__) -extern uint32_t __ICFEDIT_SE_CallGate_region_ROM_start__; -#define SE_CALLGATE_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_CallGate_region_ROM_start__) -extern uint32_t __ICFEDIT_SB_region_ROM_start__; -#define SB_REGION_ROM_START ((uint32_t)& __ICFEDIT_SB_region_ROM_start__) -extern uint32_t __ICFEDIT_SB_region_ROM_end__; -#define SB_REGION_ROM_END ((uint32_t)& __ICFEDIT_SB_region_ROM_end__) -extern uint32_t __ICFEDIT_SE_region_RAM_start__; -#define SE_REGION_RAM_START ((uint32_t)& __ICFEDIT_SE_region_RAM_start__) -extern uint32_t __ICFEDIT_SE_region_RAM_end__ ; -#define SE_REGION_RAM_END ((uint32_t)& __ICFEDIT_SE_region_RAM_end__) -extern uint32_t __ICFEDIT_SB_region_RAM_start__ ; -#define SB_REGION_RAM_START ((uint32_t)& __ICFEDIT_SB_region_RAM_start__) -extern uint32_t __ICFEDIT_SB_region_RAM_end__ ; -#define SB_REGION_RAM_END ((uint32_t)& __ICFEDIT_SB_region_RAM_end__) -extern uint32_t __ICFEDIT_SE_region_RAM_stack_top__; -#define SE_REGION_RAM_STACK_TOP ((uint32_t)& __ICFEDIT_SE_region_RAM_stack_top__) - -extern uint32_t __ICFEDIT_KMS_DataStorage_start__ ; -#define KMS_DATASTORAGE_START ((uint32_t)& __ICFEDIT_KMS_DataStorage_start__) -extern uint32_t __ICFEDIT_KMS_DataStorage_end__ ; -#define KMS_DATASTORAGE_END ((uint32_t)& __ICFEDIT_KMS_DataStorage_end__) - -#if defined (__ICCARM__) || defined(__GNUC__) -extern uint32_t __ICFEDIT_SLOT_Active_1_header__; -#define SLOT_ACTIVE_1_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_1_header__) -extern uint32_t __ICFEDIT_SLOT_Active_1_start__; -#define SLOT_ACTIVE_1_START ((uint32_t)& __ICFEDIT_SLOT_Active_1_start__) -extern uint32_t __ICFEDIT_SLOT_Active_1_end__; -#define SLOT_ACTIVE_1_END ((uint32_t)& __ICFEDIT_SLOT_Active_1_end__) -extern uint32_t __ICFEDIT_SLOT_Active_2_header__; -#define SLOT_ACTIVE_2_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_2_header__) -extern uint32_t __ICFEDIT_SLOT_Active_2_start__; -#define SLOT_ACTIVE_2_START ((uint32_t)& __ICFEDIT_SLOT_Active_2_start__) -extern uint32_t __ICFEDIT_SLOT_Active_2_end__; -#define SLOT_ACTIVE_2_END ((uint32_t)& __ICFEDIT_SLOT_Active_2_end__) -extern uint32_t __ICFEDIT_SLOT_Active_3_header__; -#define SLOT_ACTIVE_3_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_3_header__) -extern uint32_t __ICFEDIT_SLOT_Active_3_start__; -#define SLOT_ACTIVE_3_START ((uint32_t)& __ICFEDIT_SLOT_Active_3_start__) -extern uint32_t __ICFEDIT_SLOT_Active_3_end__; -#define SLOT_ACTIVE_3_END ((uint32_t)& __ICFEDIT_SLOT_Active_3_end__) -extern uint32_t __ICFEDIT_SLOT_Blob_Dwl_1_start__; -#define SLOT_BLOB_DWL_1_START ((uint32_t)& __ICFEDIT_SLOT_Blob_Dwl_1_start__) -extern uint32_t __ICFEDIT_SLOT_Blob_Dwl_1_end__; -#define SLOT_BLOB_DWL_1_END ((uint32_t)& __ICFEDIT_SLOT_Blob_Dwl_1_end__) -#endif /* __ICCARM__ || __GNUC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* MAPPING_EXPORT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld deleted file mode 100644 index 3c0a9a2b..00000000 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld +++ /dev/null @@ -1,85 +0,0 @@ -/* -** LinkerScript -*/ - -/******************************************************************************/ -/* ROM section */ -/******************************************************************************/ - -/* Vector table */ -INTVECT_start = 0x08000000; -Vector_size = 0x200; - -/* SE Code region protected by MPU isolation */ -SE_Code_region_ROM_start = INTVECT_start + Vector_size; -SE_CallGate_region_ROM_start = SE_Code_region_ROM_start + 0x4; -SE_CallGate_region_ROM_end = SE_Code_region_ROM_start + 0xFF; - -/* SE Embedded Keys */ -SE_Key_region_ROM_start = SE_CallGate_region_ROM_end + 0x1; -SE_Key_region_ROM_end = SE_Key_region_ROM_start + 0x2FF; - -/* SE Startup */ -SE_Startup_region_ROM_start = SE_Key_region_ROM_end + 0x1; -SE_Code_NoKey_region_ROM_start = SE_Startup_region_ROM_start + 0x100; -SE_Code_region_ROM_end = SE_Startup_region_ROM_start + 0x72FF; - -/* SE IF ROM */ -SE_IF_region_ROM_start = SE_Code_region_ROM_end + 0x1; -SE_IF_region_ROM_end = SE_IF_region_ROM_start + 0xEFF; - -/* SBSFU Code region */ -SB_region_ROM_start = SE_IF_region_ROM_end + 0x1; -SB_region_ROM_end = 0x0800CFFF; - -/* KMS Data Storage (NVMS) region protected area */ -/* KMS Data Storage need for 2 images : 4 kbytes * 2 ==> 8 kbytes */ -KMS_DataStorage_start = 0x0800D000; -KMS_DataStorage_end = 0x0800EFFF; - -/* ROM regions size definition */ -SE_CallGate_region_ROM_size = SE_CallGate_region_ROM_end - SE_CallGate_region_ROM_start + 0x1; -SE_Key_region_ROM_size = SE_Key_region_ROM_end - SE_Key_region_ROM_start + 0x1; -SE_Startup_region_ROM_size = SE_Code_NoKey_region_ROM_start - SE_Startup_region_ROM_start; -SE_Code_region_ROM_size = SE_Code_region_ROM_end - SE_Code_region_ROM_start + 0x1; -SE_Code_NoKey_region_ROM_size = SE_Code_region_ROM_end - SE_Code_NoKey_region_ROM_start + 0x1; -SE_IF_region_ROM_size = SE_IF_region_ROM_end - SE_IF_region_ROM_start + 0x1; -SB_region_ROM_size = SB_region_ROM_end - SB_region_ROM_start + 0x1; -KMS_DataStorage_size = KMS_DataStorage_end - KMS_DataStorage_start + 0x1; - -/******************************************************************************/ -/* RAM section */ -/* */ -/******************************************************************************/ - -/* SE RAM region */ -SE_region_RAM_start = 0x20000000; -SE_region_RAM_stack_top = 0x20000C00; /* Secure Engine's private stack */ -SE_region_RAM_end = 0x200033FF; - -/* SBSFU RAM region */ -SB_region_RAM_start = SE_region_RAM_end + 0x1; -SB_region_RAM_end = 0x20007FFF; - -/* RAM regions size definition */ -SE_region_RAM_size = SE_region_RAM_end - SE_region_RAM_stack_top + 0x1; -SB_region_RAM_size = SB_region_RAM_end - SB_region_RAM_start + 0x1; - -/******************************************************************************/ -/* RAM/ROM regions */ -/* */ -/******************************************************************************/ - -MEMORY -{ - INTVECT_ROM_region (rx) : ORIGIN = INTVECT_start, LENGTH = Vector_size - SE_CallGate_ROM_region (rx) : ORIGIN = SE_CallGate_region_ROM_start, LENGTH = SE_CallGate_region_ROM_size - SE_Key_region_ROM (rx) : ORIGIN = SE_Key_region_ROM_start, LENGTH = SE_Key_region_ROM_size - SE_Startup_ROM_region (rx) : ORIGIN = SE_Startup_region_ROM_start, LENGTH = SE_Startup_region_ROM_size - SE_ROM_region (rx) : ORIGIN = SE_CallGate_region_ROM_start, LENGTH = SE_Code_region_ROM_size - SE_Code_NoKey_ROM_region (rx) : ORIGIN = SE_Code_NoKey_region_ROM_start, LENGTH = SE_Code_NoKey_region_ROM_size - SE_IF_ROM_region (rx) : ORIGIN = SE_IF_region_ROM_start, LENGTH = SE_IF_region_ROM_size - SB_ROM_region (rx) : ORIGIN = SB_region_ROM_start, LENGTH = SB_region_ROM_size - SE_RAM_region (xrw) : ORIGIN = SE_region_RAM_stack_top, LENGTH = SE_region_RAM_size - SB_RAM_region (xrw) : ORIGIN = SB_region_RAM_start, LENGTH = SB_region_RAM_size -} diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/app_sfu.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/app_sfu.h new file mode 100644 index 00000000..7d428183 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/app_sfu.h @@ -0,0 +1,236 @@ +/** + ****************************************************************************** + * @file app_sfu.h + * @author MCD Application Team + * @brief This file contains the configuration of SBSFU application. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_SFU_H +#define APP_SFU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "se_crypto_config.h" + +/* Exported constants --------------------------------------------------------*/ +/** + * Use this define to choose the type of Firmware Image Programming you want to use. + * This version supports only 2 modes: + * + * SFU_ENCRYPTED_IMAGE: Encrypted Firmware Image + * The image is received in encrypted format. + * The image must be decrypted to be installed: + * this is done according to the selected crypto scheme, + * see @ref SECBOOT_CRYPTO_SCHEME in the SE_CoreBin part. + * + * SFU_CLEAR_IMAGE: Clear Firmware Image + * The image is received in clear format. + * No decrypt operation is needed before installing the image: + * the selected crypto scheme must be compatible with this choice, + * see @ref SECBOOT_CRYPTO_SCHEME in the SE_CoreBin part. + * + * + */ +#if SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 +#define SFU_IMAGE_PROGRAMMING_TYPE SFU_CLEAR_IMAGE +#else +#define SFU_IMAGE_PROGRAMMING_TYPE SFU_ENCRYPTED_IMAGE +#endif /* SECBOOT_CRYPTO_SCHEME */ + +#define SFU_ENCRYPTED_IMAGE (0U) /*!< The Firmware Image to be installed is downloaded in ENCRYPTED format */ +#define SFU_CLEAR_IMAGE (1U) /*!< The Firmware Image to be installed is downloaded in CLEAR format */ + +/*#define SFU_DEBUG_MODE */ /*!< Comment this define to optimize memory footprint (debug mode removed) + No more print on terminal during SBSFU execution */ + +/*#define SFU_VERBOSE_DEBUG_MODE*/ /*!< Uncomment this define when in verbose Debug mode. + this switch activates more debug prints in the console (FSM state info...) */ + + +/*#define SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE*/ /*!< You may uncomment this define when running development tests. + When this switch is activated, the FWIMG part of SB_SFU will + block when an abnormal error is encountered */ + +#if defined(SFU_VERBOSE_DEBUG_MODE) && !defined(SFU_DEBUG_MODE) +#error You cannot activate SFU_VERBOSE_DEBUG_MODE without activating SFU_DEBUG_MODE too. +#endif /* SFU_VERBOSE_DEBUG_MODE && !SFU_DEBUG_MODE */ + +#if defined(SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE) && !defined(SFU_DEBUG_MODE) +#error SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is meant to be used in DEBUG mode +#endif /* SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE && !SFU_DEBUG_MODE */ + +/*#define SFU_TEST_PROTECTION*/ /*!< Auto-test of protections : WRP, PCROP, MPU, FWALL. + Automatically executed @startup */ +#if defined(SFU_TEST_PROTECTION) +#undef SFU_DEBUG_MODE /*!< Remove definition to optimize memory footprint (debug mode removed) */ +#endif /* SFU_TEST_PROTECTION */ + +/** + * SB_SFU status LED. + * The constants below define the LED to be used and the LED blinking frequency to identify some situations. + * This is useful when no log is enabled. + * + * \li The LED blinks every see @ref SFU_COM_YMODEM_DOWNLOAD_TIMEOUT seconds when a local download is waited. + * \li For the other situations, please check the other defines below. + */ +#define SFU_STATUS_LED (LED_GREEN) /*!< LED to be used to provide the SB_SFU status to the end-user */ +#define SFU_STOP_NO_FW_BLINK_DELAY (100U) /*!< Blinks every 100ms when no valid firmware is available and the local + loader feature is disabled - see @ref SECBOOT_USE_LOCAL_LOADER */ +#define SFU_INCORRECT_OB_BLINK_DELAY (250U) /*!< Blinks every 250ms when an Option Bytes issue is detected */ + + +/** + * Optional Features Software Configuration + */ +#if !defined(SFU_TEST_PROTECTION) +#define SECBOOT_LOADER SECBOOT_USE_LOCAL_LOADER /*!< Loader selection inside SBSFU : local/standalone/none */ +#else +#define SECBOOT_LOADER SECBOOT_USE_NO_LOADER /*!< No loader usage forced when SFU_TEST_PROTECTION is set */ +#endif /* SFU_TEST_PROTECTION */ + +#define SECBOOT_USE_LOCAL_LOADER (1U) /*!< local loader feature integrated into SBSFU (YMODEM over UART) */ +#define SECBOOT_USE_STANDALONE_LOADER (2U) /*!< standalone loader : see specific loader project */ +#define SECBOOT_USE_NO_LOADER (3U) /*!< no loader capability at SBSFU stage */ + +/* Uncomment the define below if you want to use minicom with Linux */ +/* #define MINICOM_YMODEM */ /*!< YMODEM protocol handled by MINICOM (Linux): 128 bytes packets */ + +#if defined(MINICOM_YMODEM) +/* Minicom does not accept the debug prints during the YMODEM session */ +#undef SFU_VERBOSE_DEBUG_MODE +#endif /* MINICOM_YMODEM */ + + +/* Multi-images configuration : + - Max : 3 Active images + - Do not forget to add keys for each image in SE_Corebin/Binary folder + - Master slot : image started in priority if valid +*/ +#define SFU_NB_MAX_ACTIVE_IMAGE 1U /*!< 1 active image managed */ +#define SFU_NB_MAX_DWL_AREA 1U /*!< 1 blob dwl area managed */ +#define MASTER_SLOT SLOT_ACTIVE_1 /*!< SLOT_ACTIVE_1 identified as master slot */ + + +/* The define below allows disabling all security IPs at once. + * + * Enabled: all security IPs (WRP, watchdog...) are disabled. + * Disabled: the security IPs can be used (if their specific compiler switches are enabled too). + * + */ + +#define SECBOOT_DISABLE_SECURITY_IPS /*!< Disable all security IPs at once when activated */ + + +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) + +/* Uncomment the following defines when in Release mode. + In debug mode it can be better to disable some of the following protection + for a better Debug experience (WRP, RDP, IWDG, DAP, etc.) */ + +#define SFU_WRP_PROTECT_ENABLE +#define SFU_RDP_PROTECT_ENABLE +/*#define SFU_TAMPER_PROTECT_ENABLE */ /*!< WARNING : Tamper protection deactivated. As the tamper tamper pin is + neither connected to GND nor to 5V (floating level), there are too many + spurious tamper event detected */ +#define SFU_DAP_PROTECT_ENABLE /*!< WARNING: Be Careful if enabling this protection. Debugger will be disconnected. + It might be difficult to reconnect the Debugger.*/ +#define SFU_DMA_PROTECT_ENABLE +#define SFU_IWDG_PROTECT_ENABLE /*!< WARNING: + 1. Be Careful if enabling this protection. IWDG will be active also after + switching to UserApp: a refresh is needed. + 2. The IWDG reload in the SB_SFU code will have to be tuned depending on your + platform (flash size...)*/ +#define SFU_MPU_PROTECT_ENABLE /*!< MPU protection: + Enables/Disables the MPU protection. + If Secure Engine isolation is ensured by MPU (see SFU_ISOLATE_SE_WITH_MPU in + SE_CoreBin\Inc\se_low_level.h), then this switch also enables/disables it, in + addition to the overall MPU protection. */ +#define SFU_MPU_USERAPP_ACTIVATION /*!< MPU protection during UserApp execution : Only active slot(s) considered as an + executable area */ + + +/*#define SFU_FINAL_SECURE_LOCK_ENABLE */ /*!< WARNING: Should be enabled at the end of product development and test + steps. + When enabling this lock, Static protections cannot be modified any more + and Debug is finally disabled. */ + +#if defined(SFU_FINAL_SECURE_LOCK_ENABLE) +#define SFU_PROTECT_RDP_LEVEL (OB_RDP_LEVEL_2) /*!< RDP level2 for product on the field. Final OB lock, Debug + completely disabled, OB update no more possible */ + + +#else +#define SFU_PROTECT_RDP_LEVEL (OB_RDP_LEVEL_1) /*!< RDP level is set as 1 for debugging purposes. A product on the + field should set it as Level2 */ +#endif /* SFU_FINAL_SECURE_LOCK_ENABLE */ + +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ + +/** + * The define below (SECBOOT_OB_DEV_MODE) determines if the OPTION BYTES should be handled in Development mode or not. + * This define is taken into account only if RDP level 2 is not set. + * If RDP level 2 is set no modification can be done anyway. + * + * Enabled: Option Bytes Development Mode enabled. + * SB_SFU uses a "check and apply" strategy when checking the Option Bytes configuration. + * If an OB is not set though it should be then this setting is automatically corrected. + * This applies only as long as RDP level 2 is not set. + * + * Disabled: Option Bytes Development Mode disabled. + * In this mode the Option Bytes are supposed to be already configured properly when the software starts for + the first time. + * SB_SFU checks the Option Bytes configuration but does not correct it. + * If a problem is detected an error message is reported and the execution stops. + */ +#define SECBOOT_OB_DEV_MODE + + +#define SFU_IWDG_TIMEOUT ((uint32_t)15) /*!< IWDG timeout in seconds (the max. value that can be set here depends on + the prescaler settings: IWDG_PRESCALER_XXX. ) */ + + +/** + * Application Configuration + * + */ +#define SFU_FW_VERSION_START_NUM (1U) /*!< The very first version number a Firmware can have + You can also define an upper bound here if you plan to use it */ + +#define SFU_FW_VERSION_INIT_NUM (1U) /*!< The version number accepted when the header is not valid (either because + no FW installed or due to an attack attempt). Could be different from + SFU_FW_VERSION_START_NUM */ + +/** + * Features compatibility control + */ +#if defined(SFU_NO_SWAP) && defined(ENABLE_IMAGE_STATE_HANDLING) +#warning "ENABLE_IMAGE_STATE_HANDLING not compatible with SFU_NO_SWAP process" +#endif +#if defined(SFU_SECURE_USER_PROTECT_ENABLE) && defined(ENABLE_IMAGE_STATE_HANDLING) +#warning "ENABLE_IMAGE_STATE_HANDLING not compatible with SFU_SECURE_USER_PROTECT_ENABLE process" +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_SFU_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_boot.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_boot.c new file mode 100644 index 00000000..e351318b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_boot.c @@ -0,0 +1,1518 @@ +/** + ****************************************************************************** + * @file sfu_boot.c + * @author MCD Application Team + * @brief SFU BOOT module + * This file provides firmware functions to manage the following + * functionalities of the Secure Boot: + * + Initialization and de-initialization functions + * + Secure Boot Control functions + * + Secure Boot State functions + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_BOOT_C + +/* Includes ------------------------------------------------------------------*/ +#include "string.h" +#include "sfu_boot.h" +#include "sfu_loader.h" +#include "sfu_low_level_security.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level.h" +#include "sfu_fsm_states.h" +#include "sfu_error.h" +#include "stm32wlxx_it.h" /* required for the HAL Cube callbacks */ + +/* + * The sfu_com init is provided by the sfu_com_trace module by default. + * If not, then it is taken from the sfu_com_loader module. + */ +#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) +#include "sfu_trace.h" +#else +#include "sfu_trace.h" /* needed anyhow even if the defines will be empty */ +#include "sfu_com_loader.h" /* needed only for the COM init/de-init */ +#endif /* SFU_DEBUG_MODE || SFU_TEST_PROTECTION */ +#include "se_def.h" +#include "se_interface_bootloader.h" /* sfu_boot is the bootloader core part */ +#include "sfu_new_image.h" /* the local loader is a kind of "application" running in SB_SFU so it needs the + services to install a FW image */ +#include "sfu_fwimg_services.h" /* sfu_boot uses the services of the FWIMG module */ +#include "sfu_test.h" /* auto tests */ +#include "sfu_fwimg_internal.h" + +#ifdef KMS_ENABLED +#include "tkms.h" +#include "sfu_kms.h" +#endif /* KMS_ENABLED */ + +/* Private typedef -----------------------------------------------------------*/ +typedef struct +{ + SFU_BOOT_StateMachineTypeDef PrevState; /*!< The previous state of the State Machine */ + SFU_BOOT_StateMachineTypeDef CurrState; /*!< The current state of the State Machine */ +} SFU_BOOT_StateMachineContextTypeDef; /*!< Specifies a structure containing the State Machine context + information using during the SM evolution. */ + +/* Private defines -----------------------------------------------------------*/ +#define EXEC_ID_SECURE_BOOT 0U /*!< ID for Secure Boot */ +#define EXEC_ID_USER_APP 1U /*!< ID for User App */ +#define IS_VALID_EXEC_ID(EXEC_ID) (((EXEC_ID) == EXEC_ID_SECURE_BOOT) || \ + ((EXEC_ID) == EXEC_ID_USER_APP)) /*!< Check for valid ID */ + +#define RESERVED_VALUE (0xFEU) /*!< Reserved value. The reserved field used inside the LastExecStatus of the BootInfo is + maintained for future customization/expansion of the field itself */ + +#define SFU_STATE_INITIAL SFU_STATE_CHECK_STATUS_ON_RESET /*!< Define the initial state*/ + +/* Private macros ------------------------------------------------------------*/ +#define SFU_SET_SM_IF_CURR_STATE(Status, SM_STATE_OK, SM_STATE_FAILURE) \ + do{ \ + m_StateMachineContext.PrevState = m_StateMachineContext.CurrState; \ + if (Status == SFU_SUCCESS){ \ + m_StateMachineContext.CurrState = SM_STATE_OK; \ + } \ + else { \ + m_StateMachineContext.CurrState = SM_STATE_FAILURE; \ + } \ + }while(0) /*!< Set a State Machine state according to the 'Status' value*/ + + +#define SFU_SET_SM_CURR_STATE(NewState) \ + do{ \ + m_StateMachineContext.PrevState = m_StateMachineContext.CurrState; \ + m_StateMachineContext.CurrState = NewState; \ + }while(0) /*!< Set a State Machine state*/ + +/* Private variables ---------------------------------------------------------*/ +/*!< Static member variables representing the StateMachine context used during the StateMachine evolution. */ +static __IO SFU_BOOT_StateMachineContextTypeDef m_StateMachineContext = {SFU_STATE_INITIAL, + SFU_STATE_INITIAL + }; + +/*!< Static member variables identifyng the slots to be processed by secure firmware update . */ +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +static uint32_t m_DwlSlotToInstall = SLOT_INACTIVE; +#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ +static uint32_t m_ActiveSlotToExecute = SLOT_INACTIVE; + +/* Global variables ----------------------------------------------------------*/ +/** + * This variable indicates if at boot-up the FW presence check has already been performed or not: + * \li It is reset when the FW status has already been checked once and no FW is present + * \li (see @ref SFU_BOOT_SM_CheckUserFwStatus) + * \li It is used to display some messages only once in the teraterm console + * \li It is used to determine if the user button must be pressed before waiting for a local download to start + * \li This is used at LocalDownload and CheckUserFwStatus stages. + */ +uint8_t initialDeviceStatusCheck; + +/** + * Flow control initial values. + * - Security protections flow (static + dynamic) + * - Crypto operations flow (authentication, integrity) + */ +uint32_t uFlowProtectValue = FLOW_CTRL_INIT_VALUE; +uint32_t uFlowCryptoValue = FLOW_CTRL_INIT_VALUE; + +/* Private function prototypes -----------------------------------------------*/ +static SFU_ErrorStatus SFU_BOOT_Init(void); +static SFU_ErrorStatus SFU_BOOT_DeInit(void); +static void SFU_BOOT_BspConfiguration(void); +static SFU_ErrorStatus SFU_BOOT_SM_Run(void); +static void SFU_BOOT_SM_CheckStatusOnReset(void); +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +static void SFU_BOOT_SM_CheckNewFwToDownload(void); +static void SFU_BOOT_SM_DownloadNewUserFw(void); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +#ifdef KMS_ENABLED +static void SFU_BOOT_SM_CheckKMSBlobToInstall(void); +static void SFU_BOOT_SM_InstallKMSBlob(void); +#endif /* KMS_ENABLED */ +static void SFU_BOOT_SM_CheckUserFwStatus(void); +static void SFU_BOOT_SM_VerifyUserFwSignature(void); +static void SFU_BOOT_SM_ExecuteUserFw(void); +static void SFU_BOOT_SM_HandleCriticalFailure(void); +static void SFU_BOOT_SM_RebootStateMachine(void); +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +static SFU_ErrorStatus SFU_BOOT_LaunchStandaloneLoader(void); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +static SFU_ErrorStatus SFU_BOOT_SystemSecurity_Config(void); +static SFU_ErrorStatus SFU_BOOT_CheckApplySecurityProtections(void); +static SFU_ErrorStatus SFU_BOOT_SecuritySafetyCheck(void); +static void SFU_BOOT_ManageResetSources(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief This function starts the secure boot service and returns only if a configuration issue occurs. + * In the nominal case, the bootloader service runs until the user application is launched. + * When no valid user application can be run (after installing a new image or not), + * if the local loader feature is not enabled then the execution stops, + * otherwise a local download will be awaited. + * If the state machine encounters a major issue then a reboot is triggered. + * @param None. + * @note Please note that this service initializes all the required sub-services and rely on them to perform its tasks. + * @note Constraints + * 1. The system initialization must be completed (HAL, clocks, peripherals...) before calling this function. + * 2. This function also takes care of BSP initialization after enabling the secure mode. + * The BSP init code can be added in @ref SFU_BOOT_BspConfiguration(). + * 3. No other entity should handle the initialization of the Secure Engine. + * 4. The other SB_SFU services should NOT be configured by other entities if this service is used (the previous + * configurations will be overwritten). + * 5. The other SB_SFU services should NOT be used by any other entity if this service is running. + * 6. When returning from this function a reboot should be triggered (NVIC_SystemReset) after processing the + * error cause. + * 7. The caller must be prepared to never get the hand back after calling this function (jumping in user + * application by default or entering local loader state if local loader is enabled or rebooting to install a + * new image). + * @note Settings are handled at compilation time: + * 1. See compiler switches in main.h for secure IPs settings + * 2. The trace system is configured in the sfu_trace.h file + * @retval SFU_BOOT_InitErrorTypeDef error code as the function returns only if a critical failure occurs at init + * stage. + */ +SFU_BOOT_InitErrorTypeDef SFU_BOOT_RunSecureBootService() +{ + SFU_BOOT_InitErrorTypeDef e_ret_code = SFU_BOOT_INIT_ERROR; + + /* + * initialize Secure Engine variable as secure Engine is managed as a completely separate binary - not + * "automatically" managed by SBSFU compiler command + */ + if (SE_Startup() == SE_SUCCESS) + { + /* Security Configuration */ + if (SFU_BOOT_SystemSecurity_Config() == SFU_SUCCESS) + { + /* Board BSP Configuration */ + SFU_BOOT_BspConfiguration(); + + /* Configure the Secure Boot and start the State machine */ + if (SFU_BOOT_Init() == SFU_SUCCESS) + { + /* Start the Secure Boot State Machine */ + (void) SFU_BOOT_SM_Run(); + } + else + { + /* failure when initializing the secure boot service */ + e_ret_code = SFU_BOOT_INIT_FAIL; + } + } + else + { + /* failure when configuring the security IPs */ + e_ret_code = SFU_BOOT_SECIPS_CFG_FAIL; + } + } + else + { + /* failure at secure engine initialization stage */ + e_ret_code = SFU_BOOT_SECENG_INIT_FAIL; + } + + /* + * This point should not be reached unless a critical init failure occurred + * Return the error code + */ + return (e_ret_code); +} + +/** + * @brief Force System Reboot + * @param None + * @retval None + */ +void SFU_BOOT_ForceReboot(void) +{ + /* + * WARNING: The follow TRACEs are for debug only. This function could be called + * inside an IRQ so the below printf could not be executed or could generate a fault! + */ + TRACE("\r\n========= End of Execution =========="); + TRACE("\r\n\r\n\r\n"); + + /* This is the last operation executed. Force a System Reset. */ + NVIC_SystemReset(); +} + +/** + * @brief Initialize the Secure Boot State machine. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + + /* + * We start the execution at boot-up (display all messages in teraterm console, check the trigger to force a local + * download) + */ + initialDeviceStatusCheck = 1U; + + /* Call the Hardware Abstraction Layer Init implemented for the specific MCU */ + if (SFU_LL_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* Flash interface initialization */ + if (SFU_LL_FLASH_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* The COM modules is required only if the trace or the local download is enabled */ +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) + /* Call the COM module Init (already handled in SFU_BOOT_SystemSecurity_Config) */ + if (SFU_COM_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* SECBOOT_USE_LOCAL_LOADER || SFU_DEBUG_MODE || SFU_TEST_PROTECTION*/ + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + /* Call the SFU_LOADER module Init */ + if (SFU_LOADER_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* SECBOOT_USE_LOCAL_LOADER */ + + /* Call the Exception module Init */ + if (SFU_EXCPT_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* Call the image handling Init */ + if (SFU_IMG_InitImageHandling() != SFU_IMG_INIT_OK) + { + return SFU_ERROR; + } /* else continue */ + +#ifdef SFU_TEST_PROTECTION + SFU_TEST_Init(); +#endif /* SFU_TEST_PROTECTION */ + + TRACE("\r\n\r\n"); + TRACE("\r\n======================================================================"); + TRACE("\r\n= (C) COPYRIGHT 2017 STMicroelectronics ="); + TRACE("\r\n= ="); + TRACE("\r\n= Secure Boot and Secure Firmware Update ="); + TRACE("\r\n======================================================================"); + TRACE("\r\n\r\n"); + + /* Initialize the Secure Engine that will be used for all the most critical operations */ + if (SE_Init(&e_se_status, SystemCoreClock) != SE_SUCCESS) + { + TRACE("\r\n= [SBOOT] SECURE ENGINE INITIALIZATION CRITICAL FAILURE!"); + } + else + { + e_ret_status = SFU_SUCCESS; + TRACE("\r\n= [SBOOT] SECURE ENGINE INITIALIZATION SUCCESSFUL"); + } + + return e_ret_status; +} + +/** + * @brief DeInitialize the Secure Boot State machine. + * @param None + * @note Please note that in this example the de-init function is used only once to avoid a compiler warning. + * The bootloader can terminate: + * 1. with an init failure : no de-init needed + * 2. with a critical failure leading to a reboot: no de-init needed as long as no persistent info is stored + * by this function. + * 3. when launching the user app: de-init may be called here if required as long as it does not disengage the + * required security mechanisms. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_DeInit(void) +{ + if (SFU_EXCPT_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + if (SFU_LOADER_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* SECBOOT_USE_LOCAL_LOADER */ + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) + if (SFU_COM_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) */ + + if (SFU_LL_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + return SFU_SUCCESS; +} + +/** + * @brief BSP Initialization. + * Called when the secure mode is enabled. + * @note The BSP configuration should be handled only in this function. + * @param None + * @retval None + */ +static void SFU_BOOT_BspConfiguration() +{ + /* LED Init*/ + (void) BSP_LED_Init(SFU_STATUS_LED); + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + /* User Button */ + BUTTON_INIT(); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +} + +/** + * @brief Execute the Secure Boot state machine. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_SM_Run(void) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + void (*fnStateMachineFunction)(void); + static void (* fnStateMachineTable[])(void) = {SFU_BOOT_SM_CheckStatusOnReset, +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_BOOT_SM_CheckNewFwToDownload, + SFU_BOOT_SM_DownloadNewUserFw, +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +#ifdef KMS_ENABLED + SFU_BOOT_SM_CheckKMSBlobToInstall, + SFU_BOOT_SM_InstallKMSBlob, +#endif /* KMS_ENABLED */ + SFU_BOOT_SM_CheckUserFwStatus, + SFU_BOOT_SM_VerifyUserFwSignature, + SFU_BOOT_SM_ExecuteUserFw, + SFU_BOOT_SM_HandleCriticalFailure, + SFU_BOOT_SM_RebootStateMachine + }; + + /* Start the State Machine loop/evolution */ + while (e_ret_status == SFU_SUCCESS) + { + /* Always execute a security/safety check before moving to the next state */ + if (SFU_BOOT_SecuritySafetyCheck() == SFU_SUCCESS) + { + /* Get the right StateMachine function according to the current state */ + fnStateMachineFunction = fnStateMachineTable[(uint8_t)m_StateMachineContext.CurrState]; + + /* Call the State Machine function associated to the current state */ + fnStateMachineFunction(); + } + else + { + e_ret_status = SFU_ERROR; + } + } + + /* If the State Machine cannot evolve anymore, reboot is the only option */ + + /* Set the error before forcing a reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_UNKNOWN); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + + return e_ret_status; +} + +/** @brief Check the Reset status in order to understand the last cause of Reset + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_CheckStatusOnReset(void) +{ + TRACE("\r\n= [SBOOT] STATE: CHECK STATUS ON RESET"); + + /* Check the wakeup sources */ + SFU_BOOT_ManageResetSources(); + + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + /* When the local loader feature is supported we need to check if a local download is requested */ + SFU_SET_SM_CURR_STATE(SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD); +#else +#ifdef KMS_ENABLED + /* When the local loader feature is disabled go directly to the check of the KMS blob presence */ + SFU_SET_SM_CURR_STATE(SFU_STATE_CHECK_KMS_BLOB_TO_INSTALL); +#else + /* When the local loader feature is disabled go directly to the check of the FW status */ + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_STATUS); +#endif /* KMS_ENABLED */ +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +} + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * @brief Check if a new UserApp firmware is available for downloading. + * When entering this state from SFU_STATE_CHECK_STATUS_ON_RESET (initialDeviceStatusCheck=1) it is required + * to press the user button to force the local download. + * When entering this state from SFU_STATE_VERIFY_USER_FW_STATUS the local download is awaited automatically + * (because there is no other action to do). + * @param None + * @note This function must set the next State Machine State. + * @retval None + */ +static void SFU_BOOT_SM_CheckNewFwToDownload(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + + if (STANDALONE_LOADER_STATE == STANDALONE_LOADER_DWL_REQ) + { + TRACE("\r\n= [SBOOT] STATE: execution standalone loader"); + e_ret_status = SFU_BOOT_LaunchStandaloneLoader(); + + /* This is unreachable code (dead code) in principle... + At this point we should not be able to reach the following instructions. + If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); + return; + } +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + + if (initialDeviceStatusCheck == 1U) + { + /* At boot-up, before checking the FW status, a local download can be forced thanks to the user button */ + TRACE("\r\n= [SBOOT] STATE: CHECK NEW FIRMWARE TO DOWNLOAD"); + if (0U != BUTTON_PUSHED()) + { + /* Download requested */ + e_ret_status = SFU_SUCCESS; + } + else + { + e_ret_status = SFU_ERROR; + } + } + else + { + /* + * The FW status has already been checked and no FW can be launched: no need to check the trigger, wait for a local + * download to start + */ + e_ret_status = SFU_SUCCESS; + } + +#ifdef KMS_ENABLED + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_DOWNLOAD_NEW_USER_FW, SFU_STATE_CHECK_KMS_BLOB_TO_INSTALL); +#else + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_DOWNLOAD_NEW_USER_FW, SFU_STATE_VERIFY_USER_FW_STATUS); +#endif /* KMS_ENABLED */ + +} +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER)*/ + +#ifdef KMS_ENABLED +/** + * @brief Check if a KMSBlob is waiting for installation. + * This state can be entered only from SFU_STATE_CHECK_STATUS_ON_RESET when the local loader feature is + * disabled. + * This state can be entered only from SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD when the local loader feature is + * enabled. + * In this latter case, + * if a new Firmware download is requested, + * it has priority over the KMS blob installation, + * and the KMS blob installation request will be lost. + * @param None + * @note This function must set the next State Machine State. + * @retval None + */ +static void SFU_BOOT_SM_CheckKMSBlobToInstall(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_KMS_BlobInstallStateTypeDef e_PendingInstallStatus; + + /* At boot-up, before checking the FW status, we must check if a KMS blob installation is pending */ + TRACE("\r\n= [SBOOT] STATE: CHECK KMS BLOB TO INSTALL"); + + /* Check if a Blob Installation is requested or on-going */ + e_PendingInstallStatus = SFU_KMS_CheckPendingBlobInstallation(); + + if (SFU_KMS_NO_BLOBUPDATE != e_PendingInstallStatus) + { + /* Blob installation requested */ + e_ret_status = SFU_SUCCESS; + } + + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_INSTALL_KMS_BLOB, SFU_STATE_VERIFY_USER_FW_STATUS); +} + +/** + * @brief Check if a KMSBlob is waiting for install. + * When entering this state from SFU_STATE_CHECK_STATUS_ON_RESET (initialDeviceStatusCheck=1) it is required + * to press the user button to force the local download. + * When entering this state from SFU_STATE_VERIFY_USER_FW_STATUS the local download is awaited automatically + * (because there is no other action to do). + * @param None + * @note This function must set the next State Machine State. + * @retval None + */ +static void SFU_BOOT_SM_InstallKMSBlob(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t *pBlobHdr; + uint8_t *pBlobInFlash; + CK_RV e_status; + + /* At boot-up, Managing ImportBlob through KMS services. */ + TRACE("\r\n= [SBOOT] STATE: INSTALL KMS BLOB"); + + /* Here we will Launch SE service to take consume the Blob */ + /* When the Service confirms that the Blob is installed, then we can erase the SWAP */ + e_ret_status = SFU_KMS_GetBlobInstallInfo(&pBlobHdr, &pBlobInFlash); + if (e_ret_status != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN RETRIEVING BLOB LOCATION"); + } + else + { + /* Initialize KMS in order to be able to import blob using internal algorithms */ + e_status = C_Initialize(NULL); + if (e_status == CKR_OK) + { + /* we do not take the return value into account as we will not retry the import in case of issue */ + e_status = C_STM_ImportBlob(pBlobHdr, pBlobInFlash); + + if (e_status != CKR_OK) + { + (void)C_Finalize(NULL); + } + else + { + e_status = C_Finalize(NULL); + } + } + + if (e_status != CKR_OK) + { + TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN COMMUNICATING WITH KMS"); + } + + /* In any case, we remove the Blob To Install (regardless of the result) */ + e_ret_status = SFU_KMS_EraseBlob(); + + if (e_ret_status != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN ERASING KMS BLOB"); + } + + /* Display the KMS import result */ + switch (e_status) + { + case CKR_OK: + TRACE("\r\n= [SBOOT] INSTALL KMS: KMS BLOB WELL INSTALLED"); + e_ret_status = SFU_SUCCESS; + break; + + case CKR_SIGNATURE_INVALID: + /* At boot-up, Crypto Error when trying to install KMSBlob. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: BLOB AUTHENT ERROR WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + case CKR_DATA_INVALID: + /* At boot-up, Crypto Error when trying to install KMSBlob. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: BLOB FORM ERROR WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + case CKR_DEVICE_ERROR: + /* At boot-up, NVM Error when trying to install KMSBlob. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: NVM ERROR WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + case CKR_OPERATION_ACTIVE: + /* At boot-up, trying to install KMSBlob while KMS is being use. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: KMS KEYS IN USE WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + default: + TRACE("\r\n= [SBOOT] INSTALL KMS: UNKNOWN STATUS"); + e_ret_status = SFU_ERROR; + break; + } + } + + /* Set the next State Machine regardless of the KMS import result */ + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_STATUS); +} + +#endif /* KMS_ENABLED */ + + +/** + * @brief Check the Status of the Fw Image to work on in order to set the next + * State Machine state accordingly + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_CheckUserFwStatus(void) +{ +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_ErrorStatus e_ret_status = SFU_ERROR; +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + uint32_t i; + + if (initialDeviceStatusCheck == 1U) + { + TRACE("\r\n= [SBOOT] STATE: CHECK USER FW STATUS"); + } + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + if (STANDALONE_LOADER_STATE == STANDALONE_LOADER_INSTALL_REQ) + { + /* Whatever the status the decryption can be done only once ==> no interruption allowed */ + STANDALONE_LOADER_STATE = STANDALONE_LOADER_NO_REQ; + + TRACE("\r\n\t New Fw Encrypted, to be decrypted"); + + /* Check if there is a pending action related to a FW update procedure */ + if (SFU_IMG_CheckPendingInstallation(&m_DwlSlotToInstall) == SFU_IMG_FWIMAGE_TO_INSTALL) + { + /* Check the candidate version vs current active version */ + e_ret_status = SFU_IMG_CheckCandidateVersion(m_DwlSlotToInstall); + + if (SFU_SUCCESS != e_ret_status) + { + /* Erase downloaded FW in case of authentication/integrity error */ + (void) SFU_IMG_EraseDownloadedImg(m_DwlSlotToInstall); + } + else + { + /* Secure coding : double check the candidate version vs current active version */ + e_ret_status = SFU_IMG_CheckCandidateVersion(m_DwlSlotToInstall); + } + + if (SFU_SUCCESS == e_ret_status) + { + /* Start installation */ + e_ret_status = SFU_IMG_TriggerImageInstallation(m_DwlSlotToInstall); + } + } + + /* Critical failure management if installation failed */ + if (e_ret_status != SFU_SUCCESS) + { + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + return; + } + } +#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ + + /* + * No FW image installation pending : + * 1- Priority to MASTER_SLOT : check if a firmware is detected + * 2- No firmware identified : verify other slots and start execution on the last detected firmware + * 3- No active firmware candidate for execution ==> Local download + * + * This strategy can be adapted by removing for example execution of step2 ==> focus only on MASTER_SLOT. + */ + + m_ActiveSlotToExecute = 0U; + + /* 1- Priority to MASTER_SLOT : check if a firmware is detected */ + if (MASTER_SLOT != 0xFFU) + { + if (SFU_SUCCESS == SFU_IMG_DetectFW(MASTER_SLOT)) + { + m_ActiveSlotToExecute = MASTER_SLOT; + TRACE("\r\n\t A FW is detected in the slot SLOT_ACTIVE_%d", m_ActiveSlotToExecute); + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_SIGNATURE); + } + } + + /* 2- No firmware identified : verify other slots and start execution on the last detected firmware */ + if (m_ActiveSlotToExecute == 0U) + { + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) /* Slot configured ? */ + { + if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) + { + m_ActiveSlotToExecute = SLOT_ACTIVE_1 + i; + TRACE("\r\n\t A FW is detected in the slot SLOT_ACTIVE_%d", m_ActiveSlotToExecute); + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_SIGNATURE); + } + } + } + } + + /* 3- No active firmware candidate for execution ==> Local download */ + if (m_ActiveSlotToExecute == 0U) + { + /* Control if all active slot are empty */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) /* Slot configured ? */ + { + if (SFU_IMG_VerifyEmptyActiveSlot(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* + * We should never reach this code. + * Could come from an attack ==> as an example we invalidate current firmware. + */ + TRACE("\r\n\t Slot SLOT_ACTIVE_%d not empty : erasing ...", SLOT_ACTIVE_1 + i); + (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ + } + } + } + + /* + * No valid FW is present in the active slot + * and there is no FW to be installed in UserApp download area: local download (when possible) + */ + if (initialDeviceStatusCheck == 1U) + { + TRACE("\r\n\t No valid FW found in the active slots nor new FW to be installed"); +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + /* Waiting for a local download is automatic, no trigger required. */ + TRACE("\r\n\t Waiting for the local download to start... "); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + initialDeviceStatusCheck = 0U; +#ifdef SFU_TEST_PROTECTION + SFU_TEST_Reset(); +#endif /* SFU_TEST_PROTECTION */ + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + else + { + /* + * No ELSE branch (except for verbose debug), because the FW status is checked only once per boot: + * If a FW is present in the active slot => it is checked then launched. + * If there is a FW to install => the installation procedure starts. + * If no FW is present and no installation is pending: + * - if the local loader feature is enabled we enter the local download state + * - if the local loader feature is disabled, the execution is stopped. + */ + TRACE("\r\n\t Abnormal case: SFU_STATE_VERIFY_USER_FW_STATUS is not supposed to be entered more than once per boot."); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_SET_SM_CURR_STATE(SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD); +#else + /* + * When the local loader feature is disabled it is not possible to enter the "check new fw download" state. + * Rebooting automatically or keeping on checking the FW status would not necessarily be better. + * So we end up waiting for the user to reboot (or the IWDG to expire). + */ + TRACE("\r\n\t No valid FW and no local loader: execution stopped.\r\n"); + while (1 == 1) + { + (void) BSP_LED_Toggle(SFU_STATUS_LED); + HAL_Delay(SFU_STOP_NO_FW_BLINK_DELAY); + } +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + } +} + + +#if SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER +/** + * @brief A new UserApp Fw was available. Start to download it + * @param None + * @note Reset is generated at by standalone loader when FW is downloaded. + * @retval None + */ +static void SFU_BOOT_SM_DownloadNewUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + TRACE("\r\n= [SBOOT] STATE: DOWNLOAD NEW USER FIRMWARE"); + + /* Jump into standalone loader */ + STANDALONE_LOADER_STATE = STANDALONE_LOADER_DWL_REQ; + e_ret_status = SFU_BOOT_LaunchStandaloneLoader(); + + /* This is unreachable code (dead code) in principle... + At this point we should not be able to reach the following instructions. + If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} +#elif (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) +/** + * @brief A new UserApp Fw was available. Start to download it + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_DownloadNewUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_LOADER_StatusTypeDef e_ret_status_app = SFU_LOADER_ERR_COM; + uint32_t dwl_slot; + uint32_t u_size = 0; + + TRACE("\r\n= [SBOOT] STATE: DOWNLOAD NEW USER FIRMWARE"); + + /* + * Download area will be chosen as following. After header analysis : + * - same DWL slot number as SFU magic number, if the slot is configured. + * As example, we will choose SLOT_DWL_2 for SFU2 magic in the FW header + * - by default : SLOT_DWL_1 + */ + e_ret_status = SFU_LOADER_DownloadNewUserFw(&e_ret_status_app, &dwl_slot, &u_size); + if (e_ret_status == SFU_SUCCESS) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t FwSize=%d | PartialFwSize=%d | PartialFwOffset=%d | %d bytes received", + fw_image_header_validated.FwSize, fw_image_header_validated.PartialFwSize, + fw_image_header_validated.PartialFwOffset, u_size); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + /* Read header in dwl slot */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &fw_image_header_validated, (uint8_t *) SlotStartAdd[dwl_slot], + sizeof(SE_FwRawHeaderTypeDef)); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* + * In 1_Image example : dwl_slot == active_slot + */ + if (SFU_IMG_Validation(dwl_slot, &fw_image_header_validated) != SFU_SUCCESS) + { + /* CleanUp downloaded image (header preserved, for anti-rollback) */ + (void) SFU_IMG_InvalidateCurrentFirmware(dwl_slot); + + /* no specific error cause set */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Cannot memorize that a new image has been downloaded."); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + else + { + /* CleanUp downloaded image (header preserved, for anti-rollback) */ + (void) SFU_IMG_InvalidateCurrentFirmware(dwl_slot); + + /* Memorize the specific error cause if any before handling this critical failure */ + switch (e_ret_status_app) + { + case SFU_LOADER_ERR_COM: + SFU_EXCPT_SetError(SFU_EXCPT_COM_ERR); + break; + case SFU_LOADER_ERR_FW_VERSION: + SFU_EXCPT_SetError(SFU_EXCPT_VERSION_ERR); + break; + case SFU_LOADER_ERR_FW_LENGTH: + SFU_EXCPT_SetError(SFU_EXCPT_FW_TOO_BIG); + break; + case SFU_LOADER_ERR_AUTH_FAILED: + SFU_EXCPT_SetError(SFU_EXCPT_HEADER_AUTH_ERR); + break; + case SFU_LOADER_ERR_FLASH: + SFU_EXCPT_SetError(SFU_EXCPT_FLASH_ERR); + break; + case SFU_LOADER_ERR_CRYPTO: + SFU_EXCPT_SetError(SFU_EXCPT_DECRYPT_ERR); + break; + default: + /* no specific error cause */ + break; + } + } /* else error with no specific error cause */ + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_REBOOT_STATE_MACHINE, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} +#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ + + +/** + * @brief Verify the UserApp Fw signature before executing it + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_VerifyUserFwSignature(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t i; + + TRACE("\r\n= [SBOOT] STATE: VERIFY USER FW SIGNATURE"); + + /* Double security check : + - testing "static protections" twice will avoid basic hardware attack + - flow control reached : dynamic protections checked + - re-execute static then dynamic check + - errors caught by FLOW_CONTROL ==> infinite loop */ + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); + FLOW_CONTROL_INIT(uFlowProtectValue, FLOW_CTRL_INIT_VALUE); + e_ret_status = SFU_LL_SECU_CheckApplyStaticProtections(); + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_STATIC_PROTECT); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_SECU_CheckApplyRuntimeProtections(SFU_THIRD_CONFIGURATION); + } + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); + if (e_ret_status != SFU_SUCCESS) + { + /* + * Due to previous flow control, we should never reach this code : + * Critical failure management if installation failed + */ + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + return; + } + + /* + * With the 2 images handling: + * 1. the header signature is verified when installing a new firmware + * 2. the firmware signature is checked when installing a new firmware + * 3. remaining part of active slot is kept "clean" during installation procedure + * So following checks should never fail. + */ + /* Check all active slots configured */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + /* FW installed ? */ + if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) + { + /* Initialize Flow control */ + FLOW_CONTROL_INIT(uFlowCryptoValue, FLOW_CTRL_INIT_VALUE); + + /* Check the header signature */ + e_ret_status = SFU_IMG_VerifyActiveImgMetadata(SLOT_ACTIVE_1 + i); + if (SFU_SUCCESS == e_ret_status) + { + /* Check the FW signature */ + e_ret_status = SFU_IMG_VerifyActiveImg(SLOT_ACTIVE_1 + i); + if (SFU_SUCCESS == e_ret_status) + { + /* Verify that there is no additional code beyond firmware image */ + e_ret_status = SFU_IMG_VerifyActiveSlot(SLOT_ACTIVE_1 + i); + if (SFU_SUCCESS != e_ret_status) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Unexpected code beyond FW image in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Firmware signature verification failure in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Header signature verification failure in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + /* + * One of the checks fails : + * - Header signature + * - FW signature + * - No malicious code + * ==> Active slot should be invalidated + */ + if (SFU_SUCCESS != e_ret_status) + { + /* + * We should never reach this code. + * Could come from an attack ==> as an example we invalidate current firmware. + */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Erasing slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ + } + else + { + /* Verify if authentication and integrity controls performed */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); + } + } + else + { + if (SFU_IMG_VerifyEmptyActiveSlot(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* + * We should never reach this code. + * Could come from an attack ==> as an example we invalidate current firmware. + */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Slot SLOT_ACTIVE_%d not empty : erasing ...", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ + } + } + } + } + + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_EXECUTE_USER_FW, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} + +/** + * @brief Exit from the SB/SFU State Machine and try to execute the UserApp Fw + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_ExecuteUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status = SE_KO; + uint32_t i; + + TRACE("\r\n= [SBOOT] STATE: EXECUTE USER FIRMWARE"); + + /* Reload Watchdog */ + (void) SFU_LL_SECU_IWDG_Refresh(); + + /* Verify if authentication and integrity controls performed at SFU_STATE_VERIFY_USER_FW_SIGNATURE */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); + + /* Double security check for all active slots : + - Control twice the Header signature will avoid basic hardware attack + - Control twice the FW signature will avoid basic hardware attack */ + + /* Check all active slots configured */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + /* FW installed ? */ + if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) + { + /* Initialize Flow control */ + FLOW_CONTROL_INIT(uFlowCryptoValue, FLOW_CTRL_INIT_VALUE); + + /* Check the header signature */ + if (SFU_IMG_VerifyActiveImgMetadata(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } + + /* Check the FW signature */ + if (SFU_IMG_ControlActiveImgTag(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } + +#if defined(ENABLE_IMAGE_STATE_HANDLING) && !defined(SFU_NO_SWAP) + /* Move the state to SELFTEST for the new images */ + if (SFU_IMG_UpdateImageState(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* Image state cannot be changed : What to do ? + ==> decision to continue execution */ + TRACE("\r\n= [FWIMG] WARNING: IMAGE STATE CANNOT BE CHANGED!"); + } +#endif /* ENABLE_IMAGE_STATE_HANDLING && !(SFU_NO_SWAP) */ + + /* Verify if authentication and integrity controls performed */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); + } + } + } + + /* + * You may decide to implement additional checks before running the Firmware. + * For the time being we launch the FW present in the active slot. + * + * The bootloader must also take care of the security aspects: + * A.configure (if any) the external flash in execution mode with On The Fly DECryption (OTFDEC) + * B.lock the SE services the UserApp is not allowed to call + * C.leave secure boot mode + */ + + /* Configure active slot in execution mode with OTFDEC (if any) : required in case of external flash */ + e_ret_status = SFU_LL_FLASH_Config_Exe(m_ActiveSlotToExecute); + if (e_ret_status != SFU_SUCCESS) + { + /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_FLASH_CFG_ERR); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Lock part of Secure Engine services */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* Double instruction to avoid basic fault injection */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* De-initialize the SB_SFU bootloader before launching the UserApp */ + (void)SFU_BOOT_DeInit(); /* the return value is not checked, we will always try launching the UserApp */ + + /* Last flow control : lock service */ + FLOW_CONTROL_STEP(uFlowCryptoValue, FLOW_STEP_LOCK_SERVICE, FLOW_CTRL_LOCK_SERVICE); + + /* This function should not return */ + e_ret_status = SFU_IMG_LaunchActiveImg(m_ActiveSlotToExecute); + + /* This point should not be reached */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + /* We do not memorize any specific error, the FSM state is already providing the info */ + TRACE("\r\n\t SFU_IMG_LaunchActiveImg(SLOT_ACTIVE_%d) failure!", m_ActiveSlotToExecute); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + while (1 == 1) + { + ; /* wait for watchdog */ + } + } + else + { + /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_LOCK_SE_SERVICES_ERR); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + } + } + else + { + /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_LOCK_SE_SERVICES_ERR); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + } + } + + /* This is unreachable code (dead code) in principle... + At this point we should not be able to reach the following instructions. + If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} + +/** + * @brief Manage a Critical Failure occurred during the evolution of the State Machine + * @param None + * @note After a Critical Failure a Reboot will be called. + * @retval None + */ +static void SFU_BOOT_SM_HandleCriticalFailure(void) +{ + TRACE("\r\n= [SBOOT] STATE: HANDLE CRITICAL FAILURE"); + + /* It's not possible to continue without compromising the stability or the security of the solution. + The State Machine needs to be aborted and a Reset must be triggered */ + SFU_SET_SM_IF_CURR_STATE(SFU_ERROR, SFU_STATE_REBOOT_STATE_MACHINE, SFU_STATE_REBOOT_STATE_MACHINE); +} + +/** + * @brief The state machine is aborted and a Reset is triggered + * @param None + * @note You are in this condition because it's not possible to continue without + compromising the stability or the security of the solution. + * @retval None + */ +static void SFU_BOOT_SM_RebootStateMachine(void) +{ + TRACE("\r\n= [SBOOT] STATE: REBOOT STATE MACHINE"); + + /* + * In case some clean-up must be done before resetting. + * Please note that at the moment this function does not clean-up the RAM used by SB_SFU. + */ + (void)SFU_BOOT_DeInit(); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); +} + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * @brief Jump into standalone loader + * @param None + * @retval None + */ +static SFU_ErrorStatus SFU_BOOT_LaunchStandaloneLoader(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status = SE_KO; + uint32_t jump_address ; + typedef void (*Function_Pointer)(void); + Function_Pointer p_jump_to_function; + + + /* Lock part of Secure Engine services */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* Lock part of Secure Engine services */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* Give execution rights to standalone loader */ + e_ret_status = SFU_LL_SECU_SetProtectionMPU_StandaloneLoader(); + } + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Initialize address to jump */ + jump_address = *(__IO uint32_t *)(((uint32_t)LOADER_REGION_ROM_START + 4)); + p_jump_to_function = (Function_Pointer) jump_address; + + /* Initialize loader's Stack Pointer */ + __set_MSP(*(__IO uint32_t *)(LOADER_REGION_ROM_START)); + + /* Jump into loader */ + p_jump_to_function(); + } + + /* The point below should NOT be reached */ + return e_ret_status; +} +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + +/** + * @brief Check (and Apply when possible) the security/safety/integrity protections. + * The "Apply" part depends on @ref SECBOOT_OB_DEV_MODE and @ref SFU_PROTECT_RDP_LEVEL. + * @param None + * @note This operation should be done as soon as possible after a reboot. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_CheckApplySecurityProtections(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Apply Static protections involving Option Bytes */ + if (SFU_LL_SECU_CheckApplyStaticProtections() == SFU_SUCCESS) + { + /* Apply runtime protections needed to be enabled after each Reset */ + e_ret_status = SFU_LL_SECU_CheckApplyRuntimeProtections(SFU_INITIAL_CONFIGURATION); + } + + return e_ret_status; +} + +/** + * @brief System security configuration + * @param None + * @note Check and apply the security protections. This has to be done as soon + * as possible after a reset + * @retval None + */ +static SFU_ErrorStatus SFU_BOOT_SystemSecurity_Config(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + /* WARNING: The following CheckApplySecurityProtection function must be called + as soon as possible after a Reset in order to be sure the system is secured + before starting any other operation. The drawback is that the ErrorManagement + is not initialized yet, so in case of failure of this function, there will not be + any error stored into the BootInfo or other visible effects. */ + + /* Very few things are already initialized at this stage. Need additional initialization + to show a message that is added as below only in Debug/Test mode */ +#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) + (void) SFU_COM_Init(); +#endif /* SFU_DEBUG_MODE || SFU_TEST_PROTECTION */ + + if (SFU_BOOT_CheckApplySecurityProtections() != SFU_SUCCESS) + { + /* WARNING: This might be generated by an attempted attack or a bug of your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + TRACE("\r\n= [SBOOT] System Security Check failed! Rebooting..."); + } + else + { + TRACE("\r\n= [SBOOT] System Security Check successfully passed. Starting..."); + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief Periodic verification of applied protection mechanisms, in order to prevent + * a malicious code removing some of the applied security/integrity features. + * The IWDG is also refreshed in this function. + * @param None + * @note This function must be called with a frequency greater than 0.25Hz! + * Otherwise a Reset will occur. Once enabled the IWDG cannot be disabled + * So the User App should continue to refresh the IWDG counter. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_SecuritySafetyCheck(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Refresh the IWDG */ + e_ret_status = SFU_LL_SECU_IWDG_Refresh(); + + + /* Add your code here for customization: + e.g. for additional security or safety periodic check. + ... + ... + */ + return e_ret_status; +} + +/** + * @brief Manage the the Reset sources, and if the case store the error for the next steps + * @param None + * @retval None + */ +static void SFU_BOOT_ManageResetSources(void) +{ + SFU_RESET_IdTypeDef e_wakeup_source_id = SFU_RESET_UNKNOWN; + + /* Check the wakeup sources */ + SFU_LL_SECU_GetResetSources(&e_wakeup_source_id); + switch (e_wakeup_source_id) + { + /* + * Please note that the example of reset causes handling below is only a basic example to illustrate the way the + * RCC_CSR flags can be used to do so. + */ + + case SFU_RESET_WDG_RESET: + TRACE("\r\n\t WARNING: A Reboot has been triggered by a Watchdog reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_LOW_POWER: + TRACE("\r\n\t INFO: A Reboot has been triggered by a LowPower reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_HW_RESET: + TRACE("\r\n\t INFO: A Reboot has been triggered by a Hardware reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_BOR_RESET: + TRACE("\r\n\t INFO: A Reboot has been triggered by a BOR reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_SW_RESET: + TRACE("\r\n\t INFO: A Reboot has been triggered by a Software reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_OB_LOADER: + TRACE("\r\n\t WARNING: A Reboot has been triggered by an Option Bytes reload!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + default: + TRACE("\r\n\t WARNING: A Reboot has been triggered by an Unknown reset source!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + } + + /* Once the reset sources has been managed and a possible error has been set, clear the reset sources */ + SFU_LL_SECU_ClearResetSources(); +} + +/** + * @brief Implement the Cube_Hal Callback generated on the Tamper IRQ. + * @param None + * @retval None + */ +void SFU_CALLBACK_ANTITAMPER(RTC_HandleTypeDef *hrtc) +{ + UNUSED(hrtc); + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_TAMPERING_FAULT); +} + +/** + * @brief Implement the Cube_Hal Callback generated on the Memory Fault. + * @note After a Memory Fault could not be possible to execute additional code + * @param None + * @retval None + */ +void SFU_CALLBACK_MEMORYFAULT(void) +{ + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_MEMORY_FAULT); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_boot.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_boot.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_boot.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_boot.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_loader.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_loader.c new file mode 100644 index 00000000..f7599f7b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_loader.c @@ -0,0 +1,544 @@ +/** + ****************************************************************************** + * @file sfu_com_loader.c + * @author MCD Application Team + * @brief Secure Firmware Update COM module. + * This file provides set of firmware functions to manage SFU Com + * functionalities for the local loader. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level.h" +#include "sfu_low_level_security.h" +#include "sfu_com_loader.h" +#include "sfu_trace.h" + + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_TEST_PROTECTION) + +/* Private defines -----------------------------------------------------------*/ +#if defined(__ICCARM__) +#define PUTCHAR_PROTOTYPE int putchar(int ch) +#elif defined(__ARMCC_VERSION) +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#elif defined(__GNUC__) +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#endif /* __ICCARM__ */ + +#define SFU_COM_LOADER_TIME_OUT ((uint32_t )0x800U) /*!< COM Transmit and Receive Timeout*/ +#define SFU_COM_LOADER_SERIAL_TIME_OUT ((uint32_t )100U) /*!< Serial PutByte and PutString Timeout*/ + +/* Private macros ------------------------------------------------------------*/ +#define IS_CAP_LETTER(c) (((c) >= (uint8_t) 'A') && ((c) <= (uint8_t) 'F')) +#define IS_LC_LETTER(c) (((c) >= (uint8_t) 'a') && ((c) <= (uint8_t) 'f')) +#define IS_09(c) (((c) >= (uint8_t) '0') && ((c) <= (uint8_t) '9')) +#define ISVALIDHEX(c) (IS_CAP_LETTER(c) || IS_LC_LETTER(c) || IS_09(c)) +#define ISVALIDDEC(c) IS_09(c) +#define CONVERTDEC(c) ((c) - (uint8_t) '0') + +#define CONVERTHEX_ALPHA(c) (IS_CAP_LETTER(c) ? ((c) - (uint8_t) 'A' + 10U) : ((c) - (uint8_t) 'a' + 10U)) +#define CONVERTHEX(c) (IS_09(c) ? ((c) - (uint8_t) '0') : CONVERTHEX_ALPHA(c)) + +/* Private function prototypes -----------------------------------------------*/ +static HAL_StatusTypeDef ReceivePacket(uint8_t *pData, uint32_t *puLength, uint32_t uTimeOut); +static uint32_t Str2Int(uint8_t *pInputStr, uint32_t *pIntNum); + +/* Functions Definition ------------------------------------------------------*/ + +#if !defined(SFU_DEBUG_MODE) && !defined(SFU_TEST_PROTECTION) +/** + * @brief SFU Com Init function. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_Init(void) +{ +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) + setvbuf(stdout, NULL, _IONBF, 0); +#endif /* __GNUC__ */ + return SFU_LL_UART_Init(); +} + +/** + * @brief SFU Com DeInit function. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_DeInit(void) +{ + return SFU_LL_UART_DeInit(); +} + +#endif /* !SFU_DEBUG_MODE && !SFU_TEST_PROTECTION */ + +/** + * @brief Receive a file using the ymodem protocol with SFU_COM_YMODEM_CRC16. + * @param peCOMStatus: SFU_COM_YMODEM_StatusTypeDef result of reception/programming. + * @param puSize: size of received file. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise + */ +SFU_ErrorStatus SFU_COM_YMODEM_Receive(SFU_COM_YMODEM_StatusTypeDef *peCOMStatus, uint32_t *puSize) +{ + uint32_t i; + uint32_t packet_length = 0U; + uint32_t session_done = 0U; + uint32_t file_done; + uint32_t errors = 0U; + uint32_t session_begin = 0U; + uint32_t filesize = 0U; + uint32_t packets_received; + uint8_t *file_ptr; + uint8_t file_size[SFU_COM_YMODEM_FILE_SIZE_LENGTH + 1U]; + uint8_t tmp; + static uint8_t m_aPacketData[SFU_COM_YMODEM_PACKET_1K_SIZE + SFU_COM_YMODEM_PACKET_DATA_INDEX + + SFU_COM_YMODEM_PACKET_TRAILER_SIZE] __attribute__((aligned(8))); + + /* Check the pointers allocation */ + if ((peCOMStatus == NULL) || (puSize == NULL)) + { + return SFU_ERROR; + } + + *peCOMStatus = SFU_COM_YMODEM_OK; + + while ((session_done == 0U) && (*peCOMStatus == SFU_COM_YMODEM_OK)) + { + packets_received = 0U; + file_done = 0U; + while ((file_done == 0U) && (*peCOMStatus == SFU_COM_YMODEM_OK)) + { + switch (ReceivePacket(m_aPacketData, &packet_length, SFU_COM_YMODEM_DOWNLOAD_TIMEOUT)) + { + case HAL_OK: + errors = 0U; + switch (packet_length) + { + case 3U: + /* Startup sequence */ + break; + case 2U: + /* Abort by sender */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + *peCOMStatus = SFU_COM_YMODEM_ABORT; + break; + case 0U: + /* End of transmission */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + *puSize = filesize; + file_done = 1U; + break; + default: + /* Normal packet */ + if (m_aPacketData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX] != (packets_received & 0x000000FFU)) + { + /* No NACK sent for a better synchro with remote : packet will be repeated */ + } + else + { + if (packets_received == 0U) + { + /* File name packet */ + if (m_aPacketData[SFU_COM_YMODEM_PACKET_DATA_INDEX] != 0U) + { + /* File name skipped */ + i = 0U; + file_ptr = m_aPacketData + SFU_COM_YMODEM_PACKET_DATA_INDEX; + while ((*file_ptr != 0U) && (i < SFU_COM_YMODEM_FILE_NAME_LENGTH)) + { + i++; + file_ptr++; + } + /* end of file name ('\0') skipped */ + file_ptr++; + + /* File size extraction */ + i = 0U; + while ((*file_ptr != (uint8_t) ' ') && (i < SFU_COM_YMODEM_FILE_SIZE_LENGTH)) + { + file_size[i] = *file_ptr; + i++; + file_ptr++; + } + file_size[i] = (uint8_t) '\0'; + (void) Str2Int(file_size, &filesize); + + /* Header packet received callback call*/ + if (SFU_COM_YMODEM_HeaderPktRxCpltCallback((uint32_t) filesize) == SFU_SUCCESS) + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + (void) SFU_LL_UART_Flush(); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CRC16); + } + else + { + /* End session */ + tmp = SFU_COM_YMODEM_CA; + (void) SFU_LL_UART_Transmit(&tmp, 1U, SFU_COM_YMODEM_NAK_TIMEOUT); + (void) SFU_LL_UART_Transmit(&tmp, 1U, SFU_COM_YMODEM_NAK_TIMEOUT); + return SFU_ERROR; + } + } + /* File header packet is empty, end session */ + else + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + file_done = 1U; + session_done = 1U; + break; + } + } + else /* Data packet */ + { + /* Data packet received callback call*/ + if (SFU_COM_YMODEM_DataPktRxCpltCallback(&m_aPacketData[SFU_COM_YMODEM_PACKET_DATA_INDEX], + packet_length) == SFU_SUCCESS) + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + + } + else /* An error occurred while writing to Flash memory */ + { + /* End session */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + *peCOMStatus = SFU_COM_YMODEM_DATA; + } + + } + packets_received ++; + session_begin = 1; + } + break; + } + break; + case HAL_BUSY: /* Abort actually */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + *peCOMStatus = SFU_COM_YMODEM_ABORT; + break; + default: + if (session_begin > 0U) + { + errors ++; + } + if (errors > SFU_COM_YMODEM_MAX_ERRORS) + { + /* Abort communication */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + *peCOMStatus = SFU_COM_YMODEM_ABORT; + } + else + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CRC16); /* Ask for a packet */ +#ifndef MINICOM_YMODEM + /* Minicom does not accept this extra character */ + TRACE("\b."); /* Replace C char by . on display console */ +#endif /* MINICOM_YMODEM */ + /* + * Toggling the LED in case no console is available: the toggling frequency depends on + * SFU_COM_YMODEM_DOWNLOAD_TIMEOUT + */ + (void) BSP_LED_Toggle(SFU_STATUS_LED); + } + break; + } + } + } + /* Make sure the status LED is turned off */ + (void) BSP_LED_Off(SFU_STATUS_LED); + + if (*peCOMStatus == SFU_COM_YMODEM_OK) + { + return SFU_SUCCESS; + } + else + { + return SFU_ERROR; + } +} + +/** + * @brief Transmit a byte to the COM Port. + * @param uParam: The byte to be sent. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_Serial_PutByte(uint8_t uParam) +{ + return SFU_LL_UART_Transmit(&uParam, 1U, SFU_COM_LOADER_SERIAL_TIME_OUT); +} + +/** + * @brief Convert a string to an integer. + * @param pInputStr: The string to be converted. + * @param pIntNum: The integer value. + * @retval 1: Correct + * 0: Error + */ +static uint32_t Str2Int(uint8_t *pInputStr, uint32_t *pIntNum) +{ + uint32_t i = 0U; + uint32_t res = 0U; + uint32_t val = 0U; + uint8_t digit; + + if ((pInputStr[0] == (uint8_t)'0') && ((pInputStr[1] == (uint8_t)'x') || (pInputStr[1] == (uint8_t)'X'))) + { + i = 2U; + while ((i < 11U) && (pInputStr[i] != (uint8_t)'\0')) + { + if (ISVALIDHEX(pInputStr[i])) + { + digit = CONVERTHEX(pInputStr[i]); + val = (val << 4U) + digit; + } + else + { + /* Return 0, Invalid input */ + res = 0U; + break; + } + i++; + } + + /* valid result */ + if (pInputStr[i] == (uint8_t)'\0') + { + *pIntNum = val; + res = 1U; + } + } + else /* max 10-digit decimal input */ + { + while ((i < 11U) && (res != 1U)) + { + if (pInputStr[i] == (uint8_t)'\0') + { + *pIntNum = val; + /* return 1 */ + res = 1U; + } + else if (((pInputStr[i] == (uint8_t)'k') || (pInputStr[i] == (uint8_t)'K')) && (i > 0U)) + { + val = val << 10U; + *pIntNum = val; + res = 1U; + } + else if (((pInputStr[i] == (uint8_t)'m') || (pInputStr[i] == (uint8_t)'M')) && (i > 0U)) + { + val = val << 20U; + *pIntNum = val; + res = 1U; + } + else if (ISVALIDDEC(pInputStr[i])) + { + digit = CONVERTDEC(pInputStr[i]); + val = (val * 10U) + digit; + } + else + { + /* return 0, Invalid input */ + res = 0U; + break; + } + i++; + } + } + + return res; +} + +/** + * @brief Receive a packet from sender + * @param pData: pointer to received data. + * @param puLength + * 0: end of transmission + * 2: abort by sender + * >0: packet length + * @param uTimeOut: receive timeout (ms). + * @retval HAL_OK: normally return + * HAL_BUSY: abort by user + */ +static HAL_StatusTypeDef ReceivePacket(uint8_t *pData, uint32_t *puLength, uint32_t uTimeout) +{ + uint32_t crc; + uint32_t packet_size = 0U; + HAL_StatusTypeDef status; + SFU_ErrorStatus eRetStatus; + + uint8_t char1; + +#ifdef MINICOM_YMODEM + uint32_t myIdx = 0; /* index indicating where to write in pData */ +#endif /* MINICOM_YMODEM */ + + *puLength = 0U; + + /* This operation could last long. Need to refresh the Watchdog if enabled. It could be implemented as a callback*/ + (void) SFU_LL_SECU_IWDG_Refresh(); + + eRetStatus = SFU_LL_UART_Receive(&char1, 1, uTimeout); + + if (eRetStatus == SFU_SUCCESS) + { + status = HAL_OK; + + switch (char1) + { + case SFU_COM_YMODEM_SOH: + packet_size = SFU_COM_YMODEM_PACKET_SIZE; + break; + case SFU_COM_YMODEM_STX: + packet_size = SFU_COM_YMODEM_PACKET_1K_SIZE; + break; + case SFU_COM_YMODEM_EOT: + break; + case SFU_COM_YMODEM_CA: + if ((SFU_LL_UART_Receive(&char1, 1U, uTimeout) == SFU_SUCCESS) && (char1 == SFU_COM_YMODEM_CA)) + { + packet_size = 2U; + } + else + { + status = HAL_ERROR; + } + break; + case SFU_COM_YMODEM_ABORT1: + case SFU_COM_YMODEM_ABORT2: + status = HAL_BUSY; + break; + case SFU_COM_YMODEM_RB: + (void) SFU_LL_UART_Receive(&char1, 1U, uTimeout); /* Ymodem startup sequence : rb ==> 0x72 + 0x62 + 0x0D */ + (void) SFU_LL_UART_Receive(&char1, 1U, uTimeout); + packet_size = 3U; + break; + default: + status = HAL_ERROR; + break; + } + *pData = char1; + + if (packet_size >= SFU_COM_YMODEM_PACKET_SIZE) + { + +#ifndef MINICOM_YMODEM + eRetStatus = SFU_LL_UART_Receive(&pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX], + (uint16_t)(packet_size + SFU_COM_YMODEM_PACKET_OVERHEAD_SIZE), uTimeout); +#else + eRetStatus = SFU_SUCCESS; + /* Receive byte per byte until no data left or no space left in buffer */ + while ((SFU_SUCCESS == eRetStatus) && + ((myIdx + SFU_COM_YMODEM_PACKET_NUMBER_INDEX) < SFU_COM_YMODEM_PACKET_1K_SIZE + + SFU_COM_YMODEM_PACKET_DATA_INDEX + + SFU_COM_YMODEM_PACKET_TRAILER_SIZE) + ) + { + eRetStatus = SFU_LL_UART_Receive(&pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX + myIdx], + 1U, uTimeout); + myIdx++; + } + + if (myIdx > 1) + { + /* We received some bytes */ + eRetStatus = SFU_SUCCESS; + } +#endif /* MINICOM_YMODEM */ + + /* Simple packet sanity check */ + if (eRetStatus == SFU_SUCCESS) + { + status = HAL_OK; + + if (pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX] != ((pData[SFU_COM_YMODEM_PACKET_CNUMBER_INDEX]) ^ + SFU_COM_YMODEM_NEGATIVE_BYTE)) + { + packet_size = 0U; + status = HAL_ERROR; + } + else + { + /* Check packet CRC*/ + crc = (((uint32_t)pData[ packet_size + SFU_COM_YMODEM_PACKET_DATA_INDEX ]) << 8U) & 0x0000FF00U; + crc += pData[ packet_size + SFU_COM_YMODEM_PACKET_DATA_INDEX + 1U ]; + + /*Configure CRC with 16-bit polynomial*/ + if (SFU_LL_CRC_Config(SFU_CRC_CONFIG_16BIT) == SFU_SUCCESS) + { + if (SFU_LL_CRC_Calculate((uint32_t *)(uint32_t)&pData[SFU_COM_YMODEM_PACKET_DATA_INDEX], packet_size) != crc) + { + packet_size = 0U; + status = HAL_ERROR; + } + + } + else + { + packet_size = 0U; + status = HAL_ERROR; + } + } + } + else + { + status = HAL_ERROR; + } + } + } + else + { + status = HAL_ERROR; + } + + *puLength = packet_size; + return status; +} + +/** + * @brief Ymodem Header Packet Transfer completed callback. + * @param uFileSize: Dimension of the file that will be received. + * @retval None + */ +__weak SFU_ErrorStatus SFU_COM_YMODEM_HeaderPktRxCpltCallback(uint32_t uFileSize) +{ + + /* NOTE : This function should not be modified, when the callback is needed, + the SFU_COM_YMODEM_HeaderPktRxCpltCallback could be implemented in the user file + */ + UNUSED(uFileSize); + return SFU_SUCCESS; +} + +/** + * @brief Ymodem Data Packet Transfer completed callback. + * @param pData: Pointer to the buffer. + * @param uSize: Packet dimension. + * @retval None + */ +__weak SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) +{ + + /* NOTE : This function should not be modified, when the callback is needed, + the SFU_COM_YMODEM_DataPktRxCpltCallback could be implemented in the user file + */ + UNUSED(pData); + UNUSED(uSize); + return SFU_SUCCESS; +} + +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_TEST_PROTECTION) */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_loader.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_loader.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_loader.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_loader.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_trace.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_trace.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_trace.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_trace.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_trace.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_trace.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_com_trace.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_com_trace.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_def.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_def.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_def.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_def.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_error.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_error.c new file mode 100644 index 00000000..e4f31b31 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_error.c @@ -0,0 +1,228 @@ +/** + ****************************************************************************** + * @file sfu_error.c + * @author MCD Application Team + * @brief SFU ERROR + * This file provides set of firmware functions for SB_SFU errors handling. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_fsm_states.h" +#include "sfu_error.h" +#include "sfu_low_level_security.h" +#include "sfu_trace.h" +#include "se_interface_bootloader.h" +#include "sfu_fwimg_services.h" +#include "sfu_boot.h" +#include "sfu_test.h" + + +/* Private variables ---------------------------------------------------------*/ +#ifdef SFU_DEBUG_MODE +/** + * The following strings associated to the exceptions/errors are used for debugging purpose. + * WARNING: The string array must match perfectly with the @ref SFU_EXCPT_IdTypeDef. + * And the @ref SFU_EXCPT_IdTypeDef enum must be a sequence starting from 0 + */ +static char *m_aErrorStrings[] ={ "No error. Success", + "Memory fault", + "Hard fault", + "Tampering fault", + "SE lock cannot be set", +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + "Fw too big", + "File not correctly received", +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + "Fw header authentication error", + "Fw decryption error", + "Fw signature check error", + "Flash error", + "External flash configuration error.", + "Header erasing error", + "Header validation error", + "Additional code detected beyond FW", + "Fw version rejected (anti-rollback)", + "Unknown error" + }; + +#endif /* SFU_DEBUG_MODE */ + +/* Private function prototypes -----------------------------------------------*/ +static void SFU_EXCPT_RuntimeExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Print relevant errpr message. + * @param Error Error code. + * @retval None + */ +void SFU_EXCPT_SetError(SFU_EXCPT_IdTypeDef eExceptionId) +{ + if (eExceptionId <= SFU_EXCPT_UNKNOWN) + { +#ifdef SFU_DEBUG_MODE + TRACE("\r\n\t%s",m_aErrorStrings[(uint32_t) eExceptionId]); +#endif /* SFU_DEBUG_MODE */ + } +} + + +/** + * @brief Manage the Exception generated by an IRQ + * @param eExceptionId : Exception ID. + * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. + * @note Because of the interruption of the State Machine execution, + * it's not possible to continue without compromising the stability or + * the security of the solution. A System Reset is forced at the end. + * @retval None + */ +void SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId) +{ +#ifdef SFU_DEBUG_MODE + uint8_t message[150]; + uint32_t i = 0U; + + /* Avoid warning with cast frombetween char* and uint8_t* */ + while ((m_aErrorStrings[(uint32_t) eExceptionId][i] != 0u) && (i < 149U)) + { + message[i] = m_aErrorStrings[(uint32_t) eExceptionId][i]; + i++; + } + message[i] = 0U; + + /* Print relevant error message */ + TRACE_IRQ((uint8_t *)"\r\n\t "); + TRACE_IRQ(message); +#endif /* SFU_DEBUG_MODE */ + + /* Try to take an action */ + SFU_EXCPT_RuntimeExceptionHandler(eExceptionId); + + /* It's not possible to continue without compromising the stability or the security of the solution. + The State Machine needs to be aborted and a Reset must be triggered */ + SFU_BOOT_ForceReboot(); +} + +/** + * @brief Stop in case of security error + * @param eExceptionId : Exception ID. + * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ + +void SFU_EXCPT_Security_Error(void) +{ + TRACE("\r\n= [SBOOT] Security issue : execution stopped !"); + HAL_Delay(1000); + /* This is the last operation executed. Force a System Reset. */ + NVIC_SystemReset(); +} + +/** + * @brief SFU Exception Initialization. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_EXCPT_Init(void) +{ + SFU_ErrorStatus e_ret_status; + + /* ADD SRC CODE HERE + ... + */ + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} + +/** + * @brief SFU Exception DeInitialization. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_EXCPT_DeInit(void) +{ + SFU_ErrorStatus e_ret_status; + /* ADD SRC CODE HERE + ... + */ + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} + +/** + * @brief Manage the Exception/Errors/Fault at runtime, when detected + * @param eExceptionId : Exception ID. + * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. + * @note A System Reset is forced at the end by the caller of this function. + * WARNING: Be aware that this function can be called by an IRQ while + * using the printf, since the printf is not a reentrant function, and using + * the printf inside this function as well, a fault will likely occur. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static void SFU_EXCPT_RuntimeExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId) +{ + switch (eExceptionId) + { + case SFU_EXCPT_TAMPERING_FAULT: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ + break; + + case SFU_EXCPT_MEMORY_FAULT: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ + break; + + case SFU_EXCPT_HARD_FAULT: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ +#ifdef SFU_TEST_PROTECTION + /* On STM32WLXX : Hard fault IT is generated instead of memory fault when MPU accessed + ==> this is not an error */ +#endif /* SFU_TEST_PROTECTION */ + break; + + default: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ + break; + } + +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_error.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_error.h new file mode 100644 index 00000000..9188822f --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_error.h @@ -0,0 +1,85 @@ +/** + ****************************************************************************** + * @file sfu_error.h + * @author MCD Application Team + * @brief This file contains the error handling elements for SB_SFU. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_ERROR_H +#define SFU_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * This enum must start from 0. + * When adding a new error in the enum below please also: + * 1. update IS_SFU_EXCPT + * 2. update m_aErrorStrings + */ +typedef enum +{ + SFU_EXCPT_NONE = 0UL, + /* System errors */ + SFU_EXCPT_MEMORY_FAULT, + SFU_EXCPT_HARD_FAULT, + SFU_EXCPT_TAMPERING_FAULT, + /* Specific errors */ + SFU_EXCPT_LOCK_SE_SERVICES_ERR, +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + SFU_EXCPT_FW_TOO_BIG, /* The binary is too big to be installed */ + SFU_EXCPT_COM_ERR, /* COM error during the local download of the binary */ +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + SFU_EXCPT_HEADER_AUTH_ERR, /* header authentication failure */ + SFU_EXCPT_DECRYPT_ERR, /* Decrypt failure */ + SFU_EXCPT_SIGNATURE_ERR, /* Signature check failure */ + SFU_EXCPT_FLASH_ERR, /* Problem with FLASH */ + SFU_EXCPT_FLASH_CFG_ERR, /* Flash configuration issue (external flash) */ + SFU_EXCPT_HEADER_ERASING_ERR, /* Header erasing failure */ + SFU_EXCPT_HEADER_VALIDATION_ERR, /* Header validation failure */ + SFU_EXCPT_ADDITIONAL_CODE_ERR, /* Additional code detected beyond the firmware image (malicious SW) */ + SFU_EXCPT_VERSION_ERR, /* Anti-rollback check rejected the version to be installed */ + /* Unknown error */ + SFU_EXCPT_UNKNOWN /* To be kept as last error */ +} SFU_EXCPT_IdTypeDef; /*!< Errors, Exception, Faults Id */ + +/* External variables --------------------------------------------------------*/ + +/* Exported macros -----------------------------------------------------------*/ + +/* Exported functions ------------------------------------------------------- */ +void SFU_EXCPT_SetError(SFU_EXCPT_IdTypeDef eExceptionId); +void SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); +void SFU_EXCPT_Security_Error(void); + +SFU_ErrorStatus SFU_EXCPT_Init(void); +SFU_ErrorStatus SFU_EXCPT_DeInit(void); + +void SFU_EXCPT_ResetExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_ERROR_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fsm_states.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fsm_states.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_fsm_states.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fsm_states.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_common.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_common.c new file mode 100644 index 00000000..d440520f --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_common.c @@ -0,0 +1,1055 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_common.c + * @author MCD Application Team + * @brief This file provides set of firmware functions to manage the Firmware Images. + * This file contains the "common" functionalities of the image handling. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_FWIMG_COMMON_C + +/* Includes ------------------------------------------------------------------*/ +#include +#include "main.h" +#include "sfu_fsm_states.h" /* needed for sfu_error.h */ +#include "sfu_error.h" +#include "sfu_low_level.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "se_interface_bootloader.h" +#include "sfu_interface_crypto_scheme.h" +#include "sfu_fwimg_regions.h" +#include "sfu_fwimg_services.h" +#include "sfu_fwimg_internal.h" +#include "sfu_trace.h" +#include "sfu_boot.h" + + + +/* Private variables ---------------------------------------------------------*/ +static uint8_t fw_tag_validated[SFU_NB_MAX_ACTIVE_IMAGE][SE_TAG_LEN]; + +/* Global variables ----------------------------------------------------------*/ +/** + * FWIMG status variables used to log errors and display debug messages. + * This is related to FLASH operations. + * This is handled with STATUS_FWIMG. + */ +SFU_IMG_StatusTypeDef SFU_IMG_Status; +uint32_t SFU_IMG_Line; + +/** + * FW header (metadata) of the active FW in active slot: structured format (access by fields) + */ +SE_FwRawHeaderTypeDef fw_image_header_validated; + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * FW header (metadata) of the candidate FW in dwl slot: structured format (access by fields) + */ +SE_FwRawHeaderTypeDef fw_image_header_to_test; +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + +/* Functions Definition : helper ---------------------------------------------*/ +/** + * @brief Memory compare with constant time execution. + * @note Objective is to avoid basic attacks based on time execution + * @param pAdd1 Address of the first buffer to compare + * @param pAdd2 Address of the second buffer to compare + * @param Size Size of the comparison + * @retval SFU_ SUCCESS if equal, a SFU_error otherwise. + */ +SFU_ErrorStatus MemoryCompare(uint8_t *pAdd1, uint8_t *pAdd2, uint32_t Size) +{ + uint8_t result = 0x00U; + uint32_t i; + + for (i = 0U; i < Size; i++) + { + result |= pAdd1[i] ^ pAdd2[i]; + } + + if (result == 0x00U) + { + return SFU_SUCCESS; + } + else + { + return SFU_ERROR; + } +} + + +/** + * @brief Check header signature + * @param pFwImageHeader: pointer to raw header. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus VerifyHeaderSignature(SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef se_status; + uint8_t result = 0x00U; + uint32_t i; + + /* Check if the FW header is authentic : SFU1 / SFU2 / SFU3 */ + if (SFU_IMG_GetFwImageSlot(pFwImageHeader) != SLOT_INACTIVE) + { + /* Unused bytes should be set at 0x00 value + Comparison with constant time execution */ + for (i = 0U; i < sizeof(pFwImageHeader->Reserved); i++) + { + result |= pFwImageHeader->Reserved[i] ^ 0x00U; + } + + if (result == 0x00U) + { + /* Check signature of the FW header */ + if (SE_VerifyHeaderSignature(&se_status, pFwImageHeader) == SE_SUCCESS) + { + FLOW_STEP(uFlowCryptoValue, FLOW_STEP_AUTHENTICATE); + e_ret_status = SFU_SUCCESS; + } + } + } + + return e_ret_status; +} + + +/** + * @brief Secure Engine Firmware signature verification (FW in non contiguous area). + * It handles Firmware TAG verification of a complete buffer by calling + * SE_AuthenticateFW_Init, SE_AuthenticateFW_Append and SE_AuthenticateFW_Finish inside the firewall. + * @note: AES_GCM tag: In order to verify the TAG of a buffer, the function will re-encrypt it + * and at the end compare the obtained TAG with the one provided as input + * in pSE_GMCInit parameter. + * @note: SHA-256 tag: a hash of the firmware is performed and compared with the digest stored in the Firmware header. + * @param pSE_Status: Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param SlotNumber index of the slot in the list + * @param pSE_Metadata: Firmware metadata. + * @param pSE_Payload: pointer to Payload Buffer descriptor. + * @param SE_FwType: Type of Fw Image. + * This parameter can be SE_FW_IMAGE_COMPLETE or SE_FW_IMAGE_PARTIAL. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SFU_ErrorStatus VerifyFwSignatureScatter(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, + SE_FwRawHeaderTypeDef *pSE_Metadata, + SE_Ex_PayloadDescTypeDef *pSE_Payload, uint32_t SE_FwType) +{ + SE_ErrorStatus se_ret_status = SE_ERROR; + SFU_ErrorStatus sfu_ret_status = SFU_SUCCESS; + /* Loop variables */ + uint32_t i; + uint32_t j; + /* Variables to handle the FW image chunks to be injected in the verification procedure and the result */ + uint32_t fw_tag_len; /* length of the authentication tag to be verified */ + uint32_t fw_verified_total_size = 0; /* number of bytes that have been processed during authentication check */ + uint32_t fw_chunk_size; /* size of a FW chunk to be verified */ + /* Authentication tag computed in this procedure (to be compared with the one stored in the FW metadata) */ + uint8_t fw_tag_output[SE_TAG_LEN] __attribute__((aligned(8))); + /* FW chunk produced by the verification procedure if any */ + uint8_t fw_chunk[CHUNK_SIZE_SIGN_VERIFICATION] __attribute__((aligned(8))); + /* FW chunk provided as input to the verification procedure */ + uint8_t fw_image_chunk[CHUNK_SIZE_SIGN_VERIFICATION] __attribute__((aligned(8))); + /* Variables to handle the FW image (this will be split in chunks) */ + uint32_t payloadsize; + uint32_t ppayload; + uint32_t scatter_nb; + /* Variables to handle FW image size and tag */ + uint32_t fw_size; + uint8_t *fw_tag; + + /* Check the pointers allocation */ + if ((pSeStatus == NULL) || (pSE_Metadata == NULL) || (pSE_Payload == NULL)) + { + return SFU_ERROR; + } + if ((pSE_Payload->pPayload[0] == 0U) || ((pSE_Payload->pPayload[1] == 0U) && (pSE_Payload->PayloadSize[1] != 0U))) + { + return SFU_ERROR; + } + + /* Check the parameters value and set fw_size and fw_tag to check */ + if (SE_FwType == SE_FW_IMAGE_COMPLETE) + { + fw_size = pSE_Metadata->FwSize; + fw_tag = pSE_Metadata->FwTag; + } + else if (SE_FwType == SE_FW_IMAGE_PARTIAL) + { + fw_size = pSE_Metadata->PartialFwSize; + fw_tag = pSE_Metadata->PartialFwTag; + } + else + { + return SFU_ERROR; + } + + if ((pSE_Payload->PayloadSize[0] + pSE_Payload->PayloadSize[1]) != fw_size) + { + return SFU_ERROR; + } + + /* fix number of scatter block */ + if (pSE_Payload->PayloadSize[1] != 0U) + { + scatter_nb = 2U; + } + else + { + scatter_nb = 1U; + } + + + /* Encryption process*/ + se_ret_status = SE_AuthenticateFW_Init(pSeStatus, pSE_Metadata, SE_FwType); + + /* check for initialization errors */ + if ((se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) + { + for (j = 0; j < scatter_nb; j++) + { + payloadsize = pSE_Payload->PayloadSize[j]; + ppayload = pSE_Payload->pPayload[j]; + i = 0; + fw_chunk_size = CHUNK_SIZE_SIGN_VERIFICATION; + + while ((i < (payloadsize / CHUNK_SIZE_SIGN_VERIFICATION)) && (*pSeStatus == SE_OK) && + (sfu_ret_status == SFU_SUCCESS)) + { + + sfu_ret_status = SFU_LL_FLASH_Read(fw_image_chunk, (uint8_t *)ppayload, fw_chunk_size) ; + if (sfu_ret_status == SFU_SUCCESS) + { + se_ret_status = SE_AuthenticateFW_Append(pSeStatus, fw_image_chunk, (int32_t)fw_chunk_size, + fw_chunk, (int32_t *)&fw_chunk_size); + } + else + { + *pSeStatus = SE_ERR_FLASH_READ; + se_ret_status = SE_ERROR; + sfu_ret_status = SFU_ERROR; + } + ppayload += fw_chunk_size; + fw_verified_total_size += fw_chunk_size; + i++; + } + /* this the last path , size can be smaller */ + fw_chunk_size = pSE_Payload->pPayload[j] + pSE_Payload->PayloadSize[j] - ppayload; + if ((fw_chunk_size != 0U) && (se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) + { + sfu_ret_status = SFU_LL_FLASH_Read(fw_image_chunk, (uint8_t *)ppayload, fw_chunk_size) ; + if (sfu_ret_status == SFU_SUCCESS) + { + + se_ret_status = SE_AuthenticateFW_Append(pSeStatus, fw_image_chunk, + (int32_t)(payloadsize - (i * CHUNK_SIZE_SIGN_VERIFICATION)), + fw_chunk, (int32_t *)&fw_chunk_size); + } + else + { + *pSeStatus = SE_ERR_FLASH_READ; + se_ret_status = SE_ERROR; + sfu_ret_status = SFU_ERROR; + } + fw_verified_total_size += fw_chunk_size; + } + } + } + + if ((sfu_ret_status == SFU_SUCCESS) && (se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) + { + if (fw_verified_total_size <= fw_size) + { + /* Do the Finalization, check the authentication TAG*/ + fw_tag_len = sizeof(fw_tag_output); + se_ret_status = SE_AuthenticateFW_Finish(pSeStatus, fw_tag_output, (int32_t *)&fw_tag_len); + + if ((se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK) && (fw_tag_len == SE_TAG_LEN)) + { + /* Firmware tag verification */ + if (MemoryCompare(fw_tag_output, fw_tag, SE_TAG_LEN) != SFU_SUCCESS) + { + *pSeStatus = SE_SIGNATURE_ERR; + se_ret_status = SE_ERROR; + sfu_ret_status = SFU_ERROR; + + /* Save result for active slot : + to avoid single fault attack the signature will be double checked before UserApp execution */ + if ((SlotNumber >= SLOT_ACTIVE_1) && (SlotNumber < SLOT_DWL_1)) + { + (void) memset(&fw_tag_validated[SlotNumber - SLOT_ACTIVE_1][0U], 0x00, SE_TAG_LEN); + } + } + else + { + FLOW_STEP(uFlowCryptoValue, FLOW_STEP_INTEGRITY); + + /* Save result for active slot : + to avoid single fault attacje the signature will be doble checked before UserApp execution */ + if ((SlotNumber >= SLOT_ACTIVE_1) && (SlotNumber < SLOT_DWL_1)) + { + (void) memcpy(&fw_tag_validated[SlotNumber - SLOT_ACTIVE_1][0U], fw_tag_output, SE_TAG_LEN); + } + } + } + else + { + sfu_ret_status = SFU_ERROR; + } + } + else + { + sfu_ret_status = SFU_ERROR; + } + } + else + { + sfu_ret_status = SFU_ERROR; + } + return sfu_ret_status; +} + +/** + * @brief Fill authenticated info in SE_FwImage. + * @param SFU_APP_Status + * @param pBuffer + * @param BufferSize + * @retval SFU_SUCCESS if successful, a SFU_ERROR otherwise. + */ +SFU_ErrorStatus ParseFWInfo(SE_FwRawHeaderTypeDef *pFwHeader, uint8_t *pBuffer) +{ + /* Check the pointers allocation */ + if ((pFwHeader == NULL) || (pBuffer == NULL)) + { + return SFU_ERROR; + } + (void) memcpy(pFwHeader, pBuffer, sizeof(*pFwHeader)); + return SFU_SUCCESS; +} + +/** + * @brief Verify Image Header in the slot given as a parameter + * @param SlotNumber index of the slot in the list + * @param pFwImageHeader pointer to a structure to handle the header info (filled by this function) + * @note Not used in Alpha version - + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus CheckAndGetFWHeader(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* use api read to detect possible ECC error */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) pFwImageHeader, (uint8_t *) SlotHeaderAdd[SlotNumber], + sizeof(SE_FwRawHeaderTypeDef)); + if (e_ret_status == SFU_SUCCESS) + { + /* Verify signature */ + e_ret_status = VerifyHeaderSignature(pFwImageHeader); + } + return e_ret_status; +} + +/** + * @brief Verify Fw signature of binary contiguous in flash + * @param pSeStatus pointer giving the SE status result + * @param SlotNumber flash slot to check + * @param pFwImageHeader pointer to fw header + * @param SlotNumber flash slot to check + * @param SE_FwType: Type of Fw Image. + * This parameter can be SE_FW_IMAGE_COMPLETE or SE_FW_IMAGE_PARTIAL. + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus VerifyFwSignature(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, + SE_FwRawHeaderTypeDef *pFwImageHeader, + uint32_t SE_FwType) +{ + SE_Ex_PayloadDescTypeDef pse_payload; + uint32_t fw_size; + uint32_t fw_offset; + + /* put it OK, to discriminate error in SFU FWIMG parts */ + *pSeStatus = SE_OK; + + /* Check the parameters value */ + if (pFwImageHeader == NULL) + { + return SFU_ERROR; + } + if ((SE_FwType != SE_FW_IMAGE_PARTIAL) && (SE_FwType != SE_FW_IMAGE_COMPLETE)) + { + return SFU_ERROR; + } + + /* Check SE_FwType parameter, and fix size and offset accordingly */ + switch (SE_FwType) + { + case SE_FW_IMAGE_COMPLETE : + fw_size = pFwImageHeader->FwSize; + fw_offset = 0U; + break; + case SE_FW_IMAGE_PARTIAL : + fw_size = pFwImageHeader->PartialFwSize; + fw_offset = pFwImageHeader->PartialFwOffset; + break; + default : + /* error */ + fw_size = 0U; + fw_offset = 0U; + break; + } + + pse_payload.pPayload[0] = SlotStartAdd[SlotNumber] + fw_offset + SFU_IMG_IMAGE_OFFSET; + pse_payload.PayloadSize[0] = fw_size; + pse_payload.pPayload[1] = 0U; + pse_payload.PayloadSize[1] = 0U; + + return VerifyFwSignatureScatter(pSeStatus, SlotNumber, pFwImageHeader, &pse_payload, SE_FwType); +} + +/** + * @brief Verifies the validity of a slot. + * @note Control if there is no additional code beyond the firmware image (malicious SW). + * @param pSlotBegin Start address of a slot. + * @param uSlotSize Size of a slot. + * @param uFwSize Size of the firmware image. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus VerifySlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uFwSize) +{ + uint8_t *pdata; + uint32_t length; + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check is already clean */ + pdata = pSlotBegin + SFU_IMG_IMAGE_OFFSET + uFwSize; + length = uSlotSize - SFU_IMG_IMAGE_OFFSET - uFwSize; + e_ret_status = SFU_LL_FLASH_Compare(pdata, 0x00000000U, 0xFFFFFFFFU, length); + + return e_ret_status; +} + +/** + * @brief This function clean-up the flash + * @note Not designed to clean-up area inside secure engine isolation. + * @note To clean the slot without erasing the header we write "0x00" except if already written + * @param pSlotBegin Start address of a slot. + * @param uSlotSize Size of a slot. + * @param uOffset Offset in the slot to start cleanup, until end of the slot. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus CleanUpSlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uOffset) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t pdata; + uint32_t slot_begin; + SFU_LL_FLASH_write_t pattern; + SFU_LL_FLASH_write_t value; + SFU_FLASH_StatusTypeDef flash_if_info; + + /* Clean-up pattern initialization */ + (void) memset((void *)&pattern, 0x00, sizeof(SFU_LL_FLASH_write_t)); + + /* Cleaning operation */ + slot_begin = (uint32_t) pSlotBegin; + for (pdata = slot_begin + uOffset; pdata < (slot_begin + uSlotSize); pdata += sizeof(SFU_LL_FLASH_write_t)) + { + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &value, (uint8_t *) pdata, sizeof(SFU_LL_FLASH_write_t)); + + if (e_ret_status == SFU_SUCCESS) + { + /* If read succeed, then the pattern write is performed only if pattern is not already present */ + if (memcmp((void *) &value, (void *) &pattern, sizeof(SFU_LL_FLASH_write_t)) != 0) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, (uint8_t *) pdata, (uint8_t *) &pattern, + sizeof(SFU_LL_FLASH_write_t)); + } + } + else + { + /* If read fail, then the write is performed unconditionally */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, (uint8_t *) pdata, (uint8_t *) &pattern, + sizeof(SFU_LL_FLASH_write_t)); + } + + /* Reload Watchdog every 4Kbytes */ + if ((pdata % 0x1000U) == 0U) + { + (void) SFU_LL_SECU_IWDG_Refresh(); + } + } + return e_ret_status; +} + +/* Functions Definition : services ------------------------------------------- */ + +/** + * @brief FW Image Handling (FWIMG) initialization function. + * Checks the validity of the settings related to image handling (slots size and alignments...). + * @note The system initialization must have been performed before calling this function (flash driver ready to be + * used...etc...). + * Must be called first (and once) before calling the other Image handling services. + * @param None. + * @retval SFU_IMG_InitStatusTypeDef SFU_IMG_INIT_OK if successful, an error code otherwise. + */ +SFU_IMG_InitStatusTypeDef SFU_IMG_InitImageHandling(void) +{ + uint32_t i; + SFU_IMG_InitStatusTypeDef e_ret_status = SFU_IMG_INIT_OK; + + /* + * When there is no valid FW in active, the fw_image_header_validated structure is filled with 0s. + * When installing a first FW (after local download) this means that WRITE_TRAILER_MAGIC will write a SWAP magic + * starting with 0s. + * This causes an issue when calling CLEAN_TRAILER_MAGIC (because of this we added an erase that generated + * side-effects). + * To avoid all these problems we can initialize fw_image_header_validated with a non-0 value. + */ + (void) memset((uint8_t *) &fw_image_header_validated, 0xFE, sizeof(fw_image_header_validated)); + + /* + * Sanity check: let's make sure all actives slots are properly aligned with regards to flash constraints + */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { +#if defined(__GNUC__) + __IO uint32_t start_add; + start_add = SlotStartAdd[SLOT_ACTIVE_1 + i]; + if (start_add != 0U) +#else + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) +#endif /* (__GNUC__) */ + { + if (!IS_ALIGNED(SlotStartAdd[SLOT_ACTIVE_1 + i])) + { + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] SLOT_ACTIVE_%d (%x) is not properly aligned\r\n", + i + 1U, SlotStartAdd[SLOT_ACTIVE_1 + i]); + } /* else active slot is properly aligned */ + } + } + + + /* + * Sanity check: let's make sure the MAGIC patterns used by the internal algorithms match the FLASH constraints. + */ + if (0U != (uint32_t)(MAGIC_LENGTH % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] magic size (%d) is not matching the FLASH constraints\r\n", MAGIC_LENGTH); + } /* else the MAGIC patterns size is fine with regards to FLASH constraints */ + + /* + * Sanity check: let's make sure the Firmware Header Length is fine with regards to FLASH constraints + */ + if (0U != (uint32_t)(SE_FW_HEADER_TOT_LEN % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + /* The code writing the FW header in FLASH requires the FW Header length to match the FLASH constraints */ + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] FW Header size (%d) is not matching the FLASH constraints\r\n", SE_FW_HEADER_TOT_LEN); + } /* else the FW Header Length is fine with regards to FLASH constraints */ + + + /* + * Sanity check: let's make sure the active slot headers do not overlap SB code area protected by WRP + */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { +#if defined(__GNUC__) + __IO uint32_t start_add; + start_add = SlotStartAdd[SLOT_ACTIVE_1 + i]; + if (start_add != 0U) +#else + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) +#endif /* (__GNUC__) */ + { + if (((SlotStartAdd[SLOT_ACTIVE_1 + i] - FLASH_BASE) / FLASH_PAGE_SIZE) <= SFU_PROTECT_WRP_PAGE_END_1) + { + TRACE("\r\n= [FWIMG] SLOT_ACTIVE_%d overlaps SBSFU code area protected by WRP\r\n", i + 1U); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + } + } + + + + + + /* + * Sanity check: let's make sure the KMS NVM area does not overlap SB code area + */ + if (!(((SB_REGION_ROM_START) > KMS_DATASTORAGE_END) + || ((SB_REGION_ROM_END) < (KMS_DATASTORAGE_START)))) + { + TRACE("\r\n= [FWIMG] KMS NVM area overlaps SB Code area\r\n"); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + + /* + * Sanity check: let's make sure the KMS NVM area does not overlap active slots area + */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + if (!(((SlotStartAdd[SLOT_ACTIVE_1 + i]) > KMS_DATASTORAGE_END) + || ((SlotEndAdd[SLOT_ACTIVE_1 + i]) < (KMS_DATASTORAGE_START)))) + { + TRACE("\r\n= [FWIMG] KMS NVM area overlaps SLOT_ACTIVE_%d area\r\n", i + 1U); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + } + } + + + + + return e_ret_status; +} + +/** + * @brief This function makes sure the current active firmware will not be considered as valid any more. + * This function alters the FLASH content. + * @note It is up to the caller to make sure the conditions to call this primitive are met (no check performed before + * running the procedure). + * @param SlotNumber index of the slot in the list + * @retval SFU_SUCCESS if successful,SFU_ERROR error otherwise. + */ +SFU_ErrorStatus SFU_IMG_InvalidateCurrentFirmware(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Reload Watchdog */ + (void) SFU_LL_SECU_IWDG_Refresh(); + + /* erase active slot except Header (under SECoreBin protection) for the anti-rollback check during next Fw update */ + e_ret_status = CleanUpSlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), SFU_IMG_IMAGE_OFFSET); + + return (e_ret_status); +} + +/** + * @brief Verifies the validity of the active firmware image metadata. + * @note This function relies on cryptographic procedures and it is up to the caller to make sure the required + * elements have been configured. + * @note This function populates the FWIMG module variable: fw_image_header_validated + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyActiveImgMetadata(uint32_t SlotNumber) +{ + /* + * If the metadata is valid then 'fw_image_header_validated' is filled with the metadata. + */ + return (CheckAndGetFWHeader(SlotNumber, &fw_image_header_validated)); +} + +/** + * @brief Verifies the validity of the active firmware image. + * @note This function relies on cryptographic procedures and it is up to the caller to make sure the required + * elements have been configured. + * Typically, SFU_IMG_VerifyActiveImgMetadata() must have been called first to populate + * fw_image_header_validated. + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyActiveImg(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status = SE_KO; + + /* + * fw_image_header_validated MUST have been populated with valid metadata first, + */ + e_ret_status = VerifyFwSignature(&e_se_status, SlotNumber, &fw_image_header_validated, SE_FW_IMAGE_COMPLETE); +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (SFU_ERROR == e_ret_status) + { + /* We do not memorize any specific error, the FSM state is already providing the info */ + TRACE("\r\n= SFU_IMG_VerifyActiveImg failure with se_status=%d!", e_se_status); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + return (e_ret_status); +} + +/** + * @brief Verifies if no malicious code beyond Fw Image in an active slot. + * @note SFU_IMG_VerifyActiveImgMetadata() must have been called first to populate fw_image_header_validated. + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyActiveSlot(uint32_t SlotNumber) +{ + /* + * fw_image_header_validated MUST have been populated with valid metadata first, + */ + return (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), fw_image_header_validated.FwSize)); +} + +/** + * @brief Verifies if no malicious code in active slot. + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyEmptyActiveSlot(uint32_t SlotNumber) +{ + return (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), 0U)); +} + +/** + * @brief Control firmware signature + * @note This control will be done twice for security reasons (first control done in VerifyFwSignatureScatter) + * @param SlotNumber index of the slot in the list + * @retval SFU_SUCCESS if successful,SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_ControlActiveImgTag(uint32_t SlotNumber) +{ + /* + * fw_image_header_validated MUST have been populated with valid metadata first, + */ + if (MemoryCompare(fw_tag_validated[SlotNumber - SLOT_ACTIVE_1], fw_image_header_validated.FwTag, + SE_TAG_LEN) != SFU_SUCCESS) + { + return SFU_ERROR; + } + else + { + FLOW_STEP(uFlowCryptoValue, FLOW_STEP_INTEGRITY); + return SFU_SUCCESS; + } + +} + +/** + * @brief Launches the user application. + * The caller must be prepared to never get the hand back after calling this function. + * If a problem occurs, it must be memorized in the bootinfo area. + * If the caller gets the hand back then this situation must be handled as a critical error. + * @note It is up to the caller to make sure the conditions to call this primitive are met + * (typically: no security check performed before launching the firmware). + * @note This function only handles the "system" aspects. + * It is up to the caller to manage any security related action (enable ITs, disengage MPU, clean RAM...). + * Nevertheless, cleaning-up the stack and heap used by SB_SFU is part of the system actions handled by this + * function (as this needs to be done just before jumping into the user application). + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus Does not return if successful, returns SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_LaunchActiveImg(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + + /* Verify if authentication/integrity/lock SE service performed */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_LOCK_SERVICE); + + uint32_t jump_address ; + typedef void (*Function_Pointer)(void); + Function_Pointer p_jump_to_function; + +#if defined(SFU_MPU_PROTECT_ENABLE) +#if defined(SFU_MPU_USERAPP_ACTIVATION) + e_ret_status = SFU_LL_SECU_SetProtectionMPU_UserApp(); +#else + HAL_MPU_Disable(); +#endif /* SFU_MPU_USERAPP_ACTIVATION */ +#endif /* SFU_MPU_PROTECT_ENABLE */ + + /* Avoid systick interruption during UserApp start-up + systick will be re-initialized by HAL_Init() during execution of main() from UserApp */ + HAL_SuspendTick(); + + /* Initialize address of user application to jump into */ + jump_address = *(__IO uint32_t *)((SlotStartAdd[SlotNumber] + SFU_IMG_IMAGE_OFFSET + 4)); + p_jump_to_function = (Function_Pointer) jump_address; + + /* Initialize user application's Stack Pointer */ + __set_MSP(*(__IO uint32_t *)(SlotStartAdd[SlotNumber] + SFU_IMG_IMAGE_OFFSET)); + + if (SFU_SUCCESS == e_ret_status) + { + /* JUMP into User App */ + p_jump_to_function(); + } + + /* The point below should NOT be reached */ + return (e_ret_status); +} + +/** + * @brief Get the version of the active FW + * @note It is up to the caller to make sure the active slot contains a valid active FW. + * @note In the current implementation the header is checked (authentication) and no version is returned if this check + * fails. + * @param SlotNumber index of the slot in the list + * @retval the FW version if the header is valid (coded on uint16_t), 0 otherwise + */ +uint16_t SFU_IMG_GetActiveFwVersion(uint32_t SlotNumber) +{ + SE_FwRawHeaderTypeDef fw_image_header; + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint16_t version = 0; + + /* check the header of the active FW */ + e_ret_status = CheckAndGetFWHeader(SlotNumber, &fw_image_header); + if (e_ret_status == SFU_SUCCESS) + { + /* retrieve the version from the header without any further check */ + version = fw_image_header.FwVersion; + } + + return (version); +} + +/** + * @brief Detect if a FW is present in a slot. + * @note Detection done based on MAGIC header + FW signature. Header verification + * not done at this stage for timing optimization. + * @param SlotNumber index of the slot in the list + * @retval SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_DetectFW(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t *pbuffer; + uint8_t buffer[SE_FW_HEADER_TOT_LEN]; + SE_FwRawHeaderTypeDef *p_header; + + /* Read header */ + pbuffer = (uint8_t *) SlotHeaderAdd[SlotNumber]; + if (SFU_LL_FLASH_Read(buffer, pbuffer, sizeof(buffer)) == SFU_SUCCESS) + { + /* Check if the FW header is authentic : SFU1 / SFU2 / SFU3 */ + p_header = (SE_FwRawHeaderTypeDef *)(uint32_t)buffer; + if (SFU_IMG_GetFwImageSlot(p_header) != SLOT_INACTIVE) + { + /* + * Control if the first 32 bytes (could be more but time consuming ...) are significants + * At this location we should find the vector table. + * Objective is to detect if the FW image has been erased + * ==> this is the case after SFU_IMG_InvalidateCurrentFirmware() (could be an attack attempt) + */ + if (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SFU_IMG_IMAGE_OFFSET + 0x20U, 0U) != SFU_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + } + } + } + return e_ret_status; +} + +/** + * @brief Validate the active FW image in active slot by installing the header + * @param SlotNumber index of the slot in the list + * @param pFwImageHeader pointer in ram to the header to install + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ + +SFU_ErrorStatus SFU_IMG_Validation(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFWImageHeader) +{ +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_status; + + /* Header writing: encrypted part with signature */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *) SlotHeaderAdd[SlotNumber], (uint8_t *) pFWImageHeader, + SE_FW_AUTH_LEN + SE_FW_HEADER_SIGN_LEN); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + + /* Header writing : Do not update image state part */ + + /* Header writing: previous FW image fingerprint */ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *)(SlotHeaderAdd[SlotNumber] + SE_FW_HEADER_TOT_LEN - + SE_FW_HEADER_FINGERPRINT_LEN), + (uint8_t *) pFWImageHeader->PrevHeaderFingerprint, SE_FW_HEADER_FINGERPRINT_LEN); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + } + + + return e_ret_status; +#else + + /* Nothing to do header already written */ + return SFU_SUCCESS; +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +} + +/** + * @brief Get firmware image ID from header. + * @param pFwImageHeader pointer to a structure to handle the header info + * @retval Fw Id : SLOT_ACTIVE_1 / 2 /... / SFU_NB_MAX_ACTIVE_IMAGE + */ +uint32_t SFU_IMG_GetFwImageSlot(SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + uint32_t active_slot; + + if (memcmp(pFwImageHeader->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) + { + active_slot = SLOT_ACTIVE_1; + } +#if (SFU_NB_MAX_ACTIVE_IMAGE > 1) + else if (memcmp(pFwImageHeader->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) + { + active_slot = SLOT_ACTIVE_2; + } +#endif /* (SFU_NB_MAX_ACTIVE_IMAGE > 1) */ +#if (SFU_NB_MAX_ACTIVE_IMAGE > 2) + else if (memcmp(pFwImageHeader->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) + { + active_slot = SLOT_ACTIVE_3; + } +#endif /* (SFU_NB_MAX_ACTIVE_IMAGE > 2) */ + else + { + active_slot = SLOT_INACTIVE; + } + + return active_slot; +} + +/** + * @brief Check candidate image version is allowed. + * @param ActiveSlot Slot identification used in case of secure counters usage + * @param CurrentVersion Version of currently installed image if any + * @param CandidateVersion Version of candidate image + * @retval SFU_SUCCESS if candidate image version is allowed, SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus SFU_IMG_CheckFwVersion(uint32_t ActiveSlot, uint16_t CurrentVersion, uint16_t CandidateVersion) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + UNUSED(ActiveSlot); + + /* If the header of the active firmware is not valid, the CurrentVersion is 0 */ + if (CurrentVersion == 0U) + { + /* + * If the header of the active firmware is not valide (could comes from an attak atempt, we authorize only the + * installation of a specific version identified by SFU_FW_VERSION_INIT_NUM. + */ + if (CandidateVersion == SFU_FW_VERSION_INIT_NUM) + { + /* Candidate version is allowed */ + e_ret_status = SFU_SUCCESS; + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + else + { + TRACE("\r\n\t Init version:%d - Current version:%d - Candidate version:%d : Installation not allowed!", SFU_FW_VERSION_INIT_NUM, CurrentVersion, CandidateVersion); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + else + { + /* + * It is not allowed to install a Firmware with a lower version than the active firmware. + * But we authorize the re-installation of the current firmware version. + * We also check that the candidate version is at least the min. allowed version for this device. + */ + if ((CandidateVersion >= CurrentVersion) && (CandidateVersion >= SFU_FW_VERSION_START_NUM)) + { + /* Candidate version is allowed */ + e_ret_status = SFU_SUCCESS; + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + else + { + TRACE("\r\n\t Init version:%d - Current version:%d - Candidate version:%d : Installation not allowed!", SFU_FW_VERSION_INIT_NUM, CurrentVersion, CandidateVersion); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + } + + return e_ret_status; +} + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * @brief Verifies the validity of the metadata associated to a candidate image. + * The anti-rollback check is performed. + * Errors can be memorized in the bootinfo area but no action is taken in this procedure. + * @note It is up to the caller to make sure the conditions to call this primitive are met (no check performed before + * running the procedure): + * SFU_IMG_CheckPendingInstallation should be called first. + * @note For the local loader (@ref SECBOOT_USE_LOCAL_LOADER), the candidate metadata is verified by: + * @ref SFU_APP_VerifyFwHeader. + * But, SFU_IMG_CheckCandidateVersion will be called when the installation of the new image is triggered. + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ + +/* anti-rollback mechanism is tested twice to avoid basic hardware attack + ==> compiler optimization is disabled for this reason */ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O0"))) +#endif /* __ICCARM__ */ + +SFU_ErrorStatus SFU_IMG_CheckCandidateVersion(uint32_t DwlSlot) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_status; + uint32_t active_slot; + uint16_t cur_ver; + uint16_t verif_ver; + + /* + * - Candidate FW Header Authentication + * An authentication check is already performed with SFU_IMG_CheckPendingInstallation(). + * As a consequence: fw_image_header_to_test is already populated + * + * - Check version is allowed + * SFU_IMG_GetActiveFwVersion() returns 0 if the header of active firmware is not valid + */ + + /* Header analysis to find slot based on number with magic tag */ + active_slot = SFU_IMG_GetFwImageSlot(&fw_image_header_to_test); + + /* Get the version of active_slot */ + cur_ver = SFU_IMG_GetActiveFwVersion(active_slot); + + if (SFU_IMG_CheckFwVersion(active_slot, cur_ver, fw_image_header_to_test.FwVersion) != SFU_SUCCESS) + { + /* The installation is forbidden */ + /* Memorize this error as this will be handled as a critical failure */ + SFU_EXCPT_SetError(SFU_EXCPT_VERSION_ERR); + + /* We would enter an infinite loop of installation attempts if we do not clean-up the dwl slot header */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *)SlotStartAdd[DwlSlot], SFU_IMG_IMAGE_OFFSET); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + /* leave now to handle the critical failure in the appropriate FSM state */ + e_ret_status = SFU_ERROR; + } + else + { + /* the anti-rollback check succeeds: the version is fine */ + /* double check to avoid basic hardware attack attack */ + verif_ver = SFU_IMG_GetActiveFwVersion(active_slot); + e_ret_status = SFU_IMG_CheckFwVersion(active_slot, verif_ver, fw_image_header_to_test.FwVersion); + } + + /* Return the result */ + return (e_ret_status); +} +#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_internal.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_internal.h new file mode 100644 index 00000000..469b89ba --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_internal.h @@ -0,0 +1,136 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_internal.h + * @author MCD Application Team + * @brief This file contains internal definitions (private) for SFU_FWIMG functionalities. + * This file should be included only by sfu_fwimg_core.c and sfu_fwimg_services.c. + * Nevertheless, the SFU_KMS module is allowed to include it to re-use the variable + * fw_image_header_to_test to install an KMS blob. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_FWIMG_INTERNAL_H +#define SFU_FWIMG_INTERNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "se_def.h" +#include "sfu_fwimg_regions.h" +#include "kms_blob_metadata.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief Payload Buffer descriptor. + * This structure describes how a Firmware is split in Flash. + * In the nominal case a Firmware is stored in 1 contiguous area. + * But, a Firmware can be split in up to 2 areas (typically when a FW installation procedure is interrupted or after a + * decrypt operation). + */ +typedef struct +{ + uint32_t pPayload[2]; /*!< table containing payload pointer*/ + uint32_t PayloadSize[2]; /*!< table containing Payload Size*/ +} SE_Ex_PayloadDescTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/** + * @brief SFU_IMG Flash Status Type Definition + * Status of a FLASH operation. + */ +typedef enum +{ + SFU_IMG_OK = 0x0U, /*!< No problem reported */ + SFU_IMG_FLASH_ERASE_FAILED, /*!< FLASH erase failure */ + SFU_IMG_FLASH_WRITE_FAILED, /*!< FLASH write failure */ + SFU_IMG_FLASH_READ_FAILED, /*!< FLASH read failure */ +} SFU_IMG_StatusTypeDef; + +/** + * @brief RAM chunk used for decryption / comparison / swap + * it is the size of RAM buffer allocated in stack and used for decrypting/moving images. + * some function allocates 2 buffer of this size in stack. + * As image are encrypted by 128 bits blocks, this value is 16 bytes aligned. + */ +#define CHUNK_SIZE_SIGN_VERIFICATION (1024UL) /*!< Signature verification chunk size*/ + +#define SFU_IMG_CHUNK_SIZE (512UL) +#define AES_BLOCK_SIZE (16UL) /*!< Size of an AES block to check padding needs for decrypting */ + +/* Exported macros -----------------------------------------------------------*/ +/** + * @brief Status Macro + * This macros aims at capturing abnormal errors in the FWIMG sub-module (typically FLASH errors). + * When SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is activated this macro blocks the execution. + * When SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is deactivated, a log is printed in the console (if SFU_DEBUG_MODE is + * activated) and the execution continues. + */ +#if defined(SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE) +#define STATUS_FWIMG(B,A) if (B) { \ + SFU_IMG_Status=A; \ + SFU_IMG_Line = __LINE__; \ + TRACE("\r\n Abnormal error %d at line %d in %s - BLOCK", \ + SFU_IMG_Status, SFU_IMG_Line, __FILE__); \ + while(1==1){;} \ + } while(0==1){;} +#else +#define STATUS_FWIMG(B,A) if (B) { \ + SFU_IMG_Status=A; \ + SFU_IMG_Line = __LINE__; \ + TRACE("\r\n Abnormal error %d at line %d in %s - CONTINUE", \ + SFU_IMG_Status, SFU_IMG_Line, __FILE__); \ + } while(0==1){;} +#endif /* SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE */ + +/* External variables --------------------------------------------------------*/ +/** + * FWIMG status variables used to log errors and display debug messages. + * This is related to FLASH operations. + * This is handled with STATUS_FWIMG. + */ +extern SFU_IMG_StatusTypeDef SFU_IMG_Status; +extern uint32_t SFU_IMG_Line; + +extern SE_FwRawHeaderTypeDef fw_image_header_validated; +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +extern SE_FwRawHeaderTypeDef fw_image_header_to_test; +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + +/* Exported functions : helper ---------------------------------------------- */ +SFU_ErrorStatus MemoryCompare(uint8_t *pAdd1, uint8_t *pAdd2, uint32_t Size); +SFU_ErrorStatus VerifyHeaderSignature(SE_FwRawHeaderTypeDef *pFwImageHeader); +SFU_ErrorStatus VerifyFwSignatureScatter(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, + SE_FwRawHeaderTypeDef *pSE_Metadata, + SE_Ex_PayloadDescTypeDef *pSE_Payload, uint32_t SE_FwType); +SFU_ErrorStatus VerifyTag(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pSE_Metadata, + uint8_t *pPayload, uint32_t SE_FwType); +SFU_ErrorStatus ParseFWInfo(SE_FwRawHeaderTypeDef *pFwHeader, uint8_t *pBuffer); +SFU_ErrorStatus CheckAndGetFWHeader(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFwImageHeader); +SFU_ErrorStatus VerifyFwSignature(SE_StatusTypeDef *pSeStatus, uint32_t slot, SE_FwRawHeaderTypeDef *pFwImageHeader, + uint32_t SE_FwType); +SFU_ErrorStatus VerifySlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uFwSize); +SFU_ErrorStatus CleanUpSlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uOffset); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_FWIMG_INTERNAL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_regions.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_regions.h new file mode 100644 index 00000000..e97bf326 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_regions.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_regions.h + * @author MCD Application Team + * @brief This file contains FLASH regions definitions for SFU_FWIMG functionalities + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_FWIMG_REGIONS_H +#define SFU_FWIMG_REGIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "app_sfu.h" +#if defined(__ARMCC_VERSION) +#include "mapping_fwimg.h" +#elif defined (__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __ARMCC_VERSION */ +#include "se_crypto_config.h" + + +/* Exported constants --------------------------------------------------------*/ +/** + * Slot list : 2 slots per image configuration + swap + */ +#define NB_SLOTS 4U +#define SLOT_INACTIVE 0U /* this index should not be used ==> no tag found in the header */ +#define SLOT_ACTIVE_1 1U +#define SLOT_DWL_1 2U +#define SLOT_SWAP 3U + +/* Calculation of the size of a slot */ +#define SLOT_SIZE(a) (SlotEndAdd[a] - SlotStartAdd[a] + 1U) + +/* + * Design constraint: the image slot size must be a multiple of the swap area size. + * And of course both image slots must have the same size. + */ +#define SFU_IMG_REGION_IS_MULTIPLE(a,b) ((a / b * b) == a) + +/* + * Checking that the slot sizes are consistent with the .icf file + * Sizes expressed in bytes (+1 because the end address belongs to the slot) + * The checks are executed at runtime in the SFU_Img_Init() function. + */ +#define SFU_IMG_REGION_IS_SAME_SIZE(a,b) ((a) == (b)) + +/** + * Image starting offset to add to the address of 1st block + */ +#define SFU_IMG_IMAGE_OFFSET ((uint32_t)512U) + + +/* External variables --------------------------------------------------------*/ +extern const uint32_t SlotHeaderAdd[NB_SLOTS]; +extern const uint32_t SlotStartAdd[NB_SLOTS]; +extern const uint32_t SlotEndAdd[NB_SLOTS]; + +#if (defined(SFU_FWIMG_COMMON_C) || defined(SE_LOW_LEVEL_C) || defined(TEST_PROTECTIONS_C)) + +const uint32_t SlotHeaderAdd[NB_SLOTS] = { 0U, + SLOT_ACTIVE_1_HEADER, + SLOT_BLOB_DWL_1_START, + 0U, + }; +/* List of slot start address */ +const uint32_t SlotStartAdd[NB_SLOTS] = { 0U, + SLOT_ACTIVE_1_START, + SLOT_BLOB_DWL_1_START, + 0U, + }; +/* List of slot end address */ +const uint32_t SlotEndAdd[NB_SLOTS] = { 0U, + SLOT_ACTIVE_1_END, + SLOT_BLOB_DWL_1_END, + 0U, + }; +#endif /* SFU_FWIMG_COMMON_C || SE_LOW_LEVEL_C || TEST_PROTECTIONS_C || SFU_LOADER_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_FWIMG_REGIONS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_services.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_services.h new file mode 100644 index 00000000..08724f4a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_fwimg_services.h @@ -0,0 +1,97 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_services.h + * @author MCD Application Team + * @brief This file contains the 2 images handling service (SFU_FWIMG functionalities) + * API definitions. + * These services can be called by the bootloader to deal with images handling. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_FWIMG_SERVICES_H +#define SFU_FWIMG_SERVICES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "se_def.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief SFU_IMG Initialization Status Type Definition + */ +typedef enum +{ + SFU_IMG_INIT_OK = 0x0U, /*!< SFU Firmware Image Handling (FWIMG) Init OK */ + SFU_IMG_INIT_SLOTS_SIZE_ERROR, /*!< error related to slots size */ + SFU_IMG_INIT_SWAP_SETTINGS_ERROR, /*!< error related to swap settings */ + SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR, /*!< error related to flash constraints */ + SFU_IMG_INIT_CRYPTO_CONSTRAINTS_ERROR, /*!< error related to crypto constraints */ + SFU_IMG_INIT_ERROR /*!< Init is FAILED: unspecified error */ +} SFU_IMG_InitStatusTypeDef; + +/** + * @brief SFU_IMG Image Installation State Type Definition + */ +typedef enum +{ + SFU_IMG_FWIMAGE_TO_INSTALL = 0x0U, /*!< There is a FW image to be installed */ + SFU_IMG_FWUPDATE_STOPPED, /*!< A previous installation has been interrupted before it completed : resume installation */ + SFU_IMG_NO_FWUPDATE, /*!< No FW image installation pending */ + SFU_IMG_FWIMAGE_ROLLBACK, /*!< A new FW image installation has not been validated : rollback initiated @ next reset */ +} SFU_IMG_ImgInstallStateTypeDef; + +/* Exported functions ------------------------------------------------------- */ +SFU_IMG_InitStatusTypeDef SFU_IMG_InitImageHandling(void); +SFU_IMG_InitStatusTypeDef SFU_IMG_CheckSwapImageHandling(void); +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +SFU_IMG_ImgInstallStateTypeDef SFU_IMG_CheckPendingInstallation(uint32_t *pDwlSlotToInstall); +#else +SFU_IMG_ImgInstallStateTypeDef SFU_IMG_CheckPendingInstallation(uint32_t *pDwlSlotToInstall, \ + uint32_t *pActiveSlotToResume, \ + uint32_t *pActiveSlotToRollback); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +SFU_ErrorStatus SFU_IMG_CheckCandidateVersion(uint32_t DwlSlot); +#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ +SFU_ErrorStatus SFU_IMG_TriggerImageInstallation(uint32_t DwlSlot); +SFU_ErrorStatus SFU_IMG_TriggerResumeInstallation(uint32_t ActiveSlot, uint32_t DwlSlot); +SFU_ErrorStatus SFU_IMG_EraseDownloadedImg(uint32_t DwlSlot); +uint32_t SFU_IMG_GetTrailerSize(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_InvalidateCurrentFirmware(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyActiveImgMetadata(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyActiveImg(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyActiveSlot(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyEmptyActiveSlot(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_LaunchActiveImg(uint32_t SlotNumber); +uint16_t SFU_IMG_GetActiveFwVersion(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_DetectFW(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_Validation(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFWImageHeader); +SFU_ErrorStatus SFU_IMG_ControlActiveImgTag(uint32_t SlotNumber); +uint32_t SFU_IMG_GetFwImageSlot(SE_FwRawHeaderTypeDef *pFwImageHeader); +SFU_ErrorStatus SFU_IMG_CheckFwVersion(uint32_t ActiveSlot, uint16_t CurrentVersion, uint16_t CandidateVersion); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_FWIMG_SERVICES_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c new file mode 100644 index 00000000..9083965c --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c @@ -0,0 +1,747 @@ +/** + ****************************************************************************** + * @file sfu_interface_crypto_scheme.c + * @author MCD Application Team + * @brief Secure Engine Interface module. + * This file provides set of firmware functions to manage SE Interface + * functionalities. These services are used by the bootloader. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" /* se_interface_bootloader.c is compiled in SBSFU project using main.h from this project */ +#include "se_low_level.h" /* This file is part of SE_CoreBin and adapts the Secure Engine (and its interface) to the + STM32 board specificities */ +#include "tkms.h" +#include "sfu_interface_crypto_scheme.h" +#include +#include "kms_platf_objects_interface.h" /* To get keys handle definitions */ + +/* Private defines -----------------------------------------------------------*/ +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) +#define GCM_TAGBITS_SIZE 128 +#define GCM_IVLEN_BITS 16 +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + +/* Private variables ---------------------------------------------------------*/ +CK_SESSION_HANDLE EncryptSession; +CK_SESSION_HANDLE DecryptSession; +CK_SESSION_HANDLE AuthenticateSession; +CK_SESSION_HANDLE VerifySession; +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) +static uint8_t *gcm_tag_header; +#endif /* SECBOOT_CRYPTO_SCHEME */ + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Get AES key handle. + * @param pxSE_Metadata Metadata that will be used to identify the keys. + * @param phAESKey pointer on AES key object handle + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) +static SE_ErrorStatus SFU_GetAESKeyObject(SE_FwRawHeaderTypeDef *pxSE_Metadata, CK_OBJECT_HANDLE *phAESKey) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + /* Each magic corresponds to a different key: + * SFUM_1 = SBSFU_KEY_1 + * SFUM_2 = SBSFU_KEY_2 + * SFUM_3 = SBSFU_KEY_3 + */ + if (memcmp(pxSE_Metadata->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) + { + *phAESKey = KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#if (SFU_NB_MAX_ACTIVE_IMAGE > 1U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) + { + *phAESKey = KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 1) */ +#if (SFU_NB_MAX_ACTIVE_IMAGE > 2U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) + { + *phAESKey = KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 2) */ + else + { + e_ret_status = SE_ERROR; + } + + return e_ret_status; +} +#endif /* ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) */ + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) +/** + * @brief Get ECDSA key handle. + * @param pxSE_Metadata Metadata that will be used to identify the keys. + * @param phAESKey pointer on AES key object handle + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +static SE_ErrorStatus SFU_GetECDSAKeyObject(SE_FwRawHeaderTypeDef *pxSE_Metadata, CK_OBJECT_HANDLE *phECDSAKey) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + /* Each magic corresponds to a different key: + * SFUM_1 = SBSFU_KEY_1 + * SFUM_2 = SBSFU_KEY_2 + * SFUM_3 = SBSFU_KEY_3 + */ + if (memcmp(pxSE_Metadata->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) + { + *phECDSAKey = KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#if (SFU_NB_MAX_ACTIVE_IMAGE > 1U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) + { + *phECDSAKey = KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 1) */ +#if (SFU_NB_MAX_ACTIVE_IMAGE > 2U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) + { + *phECDSAKey = KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 2) */ + else + { + e_ret_status = SE_ERROR; + } + + return e_ret_status; +} +#endif /*((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) */ + + +/** + * @brief Secure Engine Decrypt Init function. + * It is a wrapper of Decrypt_Init function included in the protected area. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pxSE_Metadata Metadata that will be used to fill the Crypto Init structure. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_Decrypt_Init(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxSE_Metadata, uint32_t SE_FwType) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + CK_RV rv = CKR_OK; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint8_t *gcm_iv = pxSE_Metadata->Nonce; + CK_OBJECT_HANDLE hAESKey = 0UL; + + CK_GCM_PARAMS kms_test_gcm_params = + { + (CK_BYTE *)gcm_iv, + SE_NONCE_LEN, + NULL, + 0, + GCM_TAGBITS_SIZE + }; + + CK_MECHANISM cktest_aes_gcm_mechanism = + { + CKM_AES_GCM, + (CK_VOID_PTR *) &kms_test_gcm_params, + sizeof(kms_test_gcm_params) + }; + + gcm_tag_header = pxSE_Metadata->FwTag; + +#elif (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + CK_RV rv = CKR_OK; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint8_t *iv_cbc = pxSE_Metadata->InitVector; + CK_OBJECT_HANDLE hAESKey = 0UL; + + CK_MECHANISM cktest_aes_cbc_mechanism = + { + CKM_AES_CBC, + iv_cbc, + SE_IV_LEN + }; +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* + * In this crypto scheme the Firmware is not encrypted. + * The Decrypt operation is called anyhow before installing the firmware. + * Indeed, it allows moving the Firmware image blocks in FLASH. + * These moves are mandatory to create the appropriate mapping in FLASH + * allowing the swap procedure to run without using the swap area at each and every move. + * + * See in SB_SFU project: @ref SFU_IMG_PrepareCandidateImageForInstall. + */ +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Check the pointer allocation */ + if (pxSE_Metadata == NULL) + { + return SE_ERROR; + } +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + /* Initialize the KMS service */ + C_Initialize(NULL) ; + + /* Start by opening a session */ + rv = C_OpenSession(0, session_flags, NULL, 0, &DecryptSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetAESKeyObject(pxSE_Metadata, &hAESKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#endif /* (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) */ + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + if (se_status == SE_SUCCESS) + { + /* Initialize the decryption session */ + rv = C_DecryptInit(DecryptSession, &cktest_aes_gcm_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + +#elif (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + /* Initialize the decryption session */ + if (se_status == SE_SUCCESS) + { + rv = C_DecryptInit(DecryptSession, &cktest_aes_cbc_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* Nothing to do as we won't decrypt anything */ +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + return se_status; +} + +/** + * @brief Secure Engine Decrypt Append function. + * It is a wrapper of Decrypt_Append function included in the protected area. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pInputBuffer pointer to Input Buffer. + * @param uInputSize Input Size (bytes). + * @param pOutputBuffe pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_Decrypt_Append(SE_StatusTypeDef *peSE_Status, const uint8_t *pInputBuffer, int32_t InputSize, + uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + CK_RV rv = CKR_OK; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + + /* DecryptImageInDwlSlot() always starts by calling the Decrypt service with a 0 byte buffer */ + if (0 == InputSize) + { + /* Nothing to do but we must return a success for the decrypt operation to continue */ + return (SE_SUCCESS); + } + + /* Check the pointers allocation */ + if ((pInputBuffer == NULL) || (pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + /* Buffer decryption */ + rv = C_DecryptUpdate(DecryptSession, (CK_BYTE *)pInputBuffer, InputSize, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* + * The firmware is not encrypted. + * The only thing we need to do is to recopy the input buffer in the output buffer + */ + (void)memcpy(pOutputBuffer, pInputBuffer, (uint32_t)InputSize); + *pOutputSize = InputSize; + se_status = SE_SUCCESS; +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + + return se_status; +} + +/** + * @brief Secure Engine Decrypt Finish function. + * It is a wrapper of Decrypt_Finish function included in the protected area. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pOutputBuffer pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_Decrypt_Finish(SE_StatusTypeDef *peSE_Status, uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + *peSE_Status = SE_OK; + SE_ErrorStatus se_status = SE_SUCCESS; +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + CK_RV rv = CKR_OK; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + + /* Check the pointers allocation */ + if ((pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + memcpy(pOutputBuffer, gcm_tag_header, 16); + + /* End-up decryption session */ + rv = C_DecryptFinal(DecryptSession, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* Nothing to do */ + se_status = SE_SUCCESS; +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + /* Close the session */ + rv = C_CloseSession(DecryptSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* End-up the KMS service */ + C_Finalize(NULL) ; +#endif /* (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) */ + + return se_status; +} + +/** + * @brief Secure Engine Firmware Authentication Init function. + * It is a wrapper of AuthenticateFW_Init function included in the Firewall. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pxSE_Metadata Metadata that will be used to fill the Crypto Init structure. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_AuthenticateFW_Init(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxSE_Metadata, + uint32_t SE_FwType) +{ + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_RV rv = CKR_OK; + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + uint8_t *gcm_iv = pxSE_Metadata->Nonce; + CK_OBJECT_HANDLE hAESKey; + + CK_GCM_PARAMS kms_test_gcm_params = + { + (CK_BYTE *)gcm_iv, + SE_NONCE_LEN, + NULL, + 0, + GCM_TAGBITS_SIZE + }; + + CK_MECHANISM cktest_aes_gcm_mechanism = + { + CKM_AES_GCM, + (CK_VOID_PTR *) &kms_test_gcm_params, + sizeof(kms_test_gcm_params) + }; + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + CK_MECHANISM cktest_sha_256_mechanism = + { + CKM_SHA256, + NULL, + 0 + }; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Check the pointer allocation */ + if (pxSE_Metadata == NULL) + { + return SE_ERROR; + } + + /* Initialize the KMS service */ + C_Initialize(NULL) ; + + /* Start by opening a session */ + rv = C_OpenSession(0, session_flags, NULL, 0, &AuthenticateSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetAESKeyObject(pxSE_Metadata, &hAESKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* Initialize encryption session */ + rv = C_EncryptInit(AuthenticateSession, &cktest_aes_gcm_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + /* Digest initialization */ + rv = C_DigestInit(AuthenticateSession, &cktest_sha_256_mechanism); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + return se_status; +} + +/** + * @brief Secure Engine Firmware Authentication Append function. + * It is a wrapper of AuthenticateFW_Append function included in the Firewall. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pInputBuffer pointer to Input Buffer. + * @param uInputSize Input Size (bytes). + * @param pOutputBuffer pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_AuthenticateFW_Append(SE_StatusTypeDef *peSE_Status, const uint8_t *pInputBuffer, int32_t InputSize, + uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + CK_RV rv = CKR_OK; + + /* Check the pointers allocation */ + if ((pInputBuffer == NULL) || (pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* Buffer encryption */ + rv = C_EncryptUpdate(AuthenticateSession, (CK_BYTE *)pInputBuffer, InputSize, pOutputBuffer, + (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + /* Digest calculation */ + rv = C_DigestUpdate(AuthenticateSession, (CK_BYTE_PTR)pInputBuffer, InputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + return se_status; +} + +/** + * @brief Secure Engine Firmware Authentication Finish function. + * It is a wrapper of AuthenticateFW_Finish function included in the Firewall. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pOutputBuffer pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_AuthenticateFW_Finish(SE_StatusTypeDef *peSE_Status, uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + CK_RV rv = CKR_OK; + + /* Check the pointers allocation */ + if ((pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* End-up encryption session */ + rv = C_EncryptFinal(AuthenticateSession, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + /* End-up Digest calculation */ + rv = C_DigestFinal(AuthenticateSession, (CK_BYTE_PTR)pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Close the session */ + rv = C_CloseSession(AuthenticateSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* End-up the KMS service */ + C_Finalize(NULL) ; + + return se_status; +} + +/** + * @brief Secure Engine Verify Raw Fw Header Tag. + * It verifies the signature of a raw header file. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pFwRawHeader pointer to RawHeader Buffer. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_VerifyHeaderSignature(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxFwRawHeader) +{ + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_RV rv = CKR_OK; + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + int32_t fw_raw_header_output_length = SE_TAG_LEN; + uint8_t *gcm_iv = pxFwRawHeader->Nonce; + SE_FwRawHeaderTypeDef *gcm_header = pxFwRawHeader; + CK_OBJECT_HANDLE hAESKey = 0UL; + + CK_GCM_PARAMS kms_test_gcm_params = + { + (CK_BYTE *)gcm_iv, + SE_NONCE_LEN, + (CK_BYTE_PTR)gcm_header, + ((int32_t)SE_FW_AUTH_LEN), + GCM_TAGBITS_SIZE + }; + + CK_MECHANISM cktest_aes_gcm_mechanism = + { + CKM_AES_GCM, + (CK_VOID_PTR *) &kms_test_gcm_params, + sizeof(kms_test_gcm_params) + }; + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) + + const uint8_t *pPayload; /* Metadata payload */ + int32_t payloadSize; /* Metadata length to be considered for hash */ + uint8_t *pSignature = pxFwRawHeader->HeaderSignature; /* Signature ECDSA */ + CK_OBJECT_HANDLE hECDSAKey = 0UL; + CK_MECHANISM cktest_ecdsa_256_mechanism = + { + CKM_ECDSA_SHA256, + NULL, + 0 + }; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Check the pointers allocation */ + if (NULL == pxFwRawHeader) + { + *peSE_Status = SE_KO; + return SE_ERROR; + } + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + gcm_tag_header = pxFwRawHeader->HeaderSignature; +#endif /* SECBOOT_CRYPTO_SCHEME */ + + + /* Initialize the KMS service */ + C_Initialize(NULL) ; + + /* Start by opening a session */ + rv = C_OpenSession(0, session_flags, NULL, 0, &VerifySession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetAESKeyObject(pxFwRawHeader, &hAESKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* Initialize the decryption session */ + rv = C_DecryptInit(VerifySession, &cktest_aes_gcm_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + + /* End-up decryption session : control if the tag is correct */ + rv = C_DecryptFinal(VerifySession, gcm_tag_header, (CK_ULONG_PTR)&fw_raw_header_output_length); + + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) + + pPayload = (const uint8_t *)pxFwRawHeader; + payloadSize = SE_FW_AUTH_LEN; /* Authenticated part of the header */ + + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetECDSAKeyObject(pxFwRawHeader, &hECDSAKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* Initialize the verification process */ + rv = C_VerifyInit(VerifySession, &cktest_ecdsa_256_mechanism, hECDSAKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + + /* End-up verification process : control if the signature is correct */ + rv = C_Verify(VerifySession, (CK_BYTE_PTR)pPayload, payloadSize, (CK_BYTE_PTR)pSignature, SE_HEADER_SIGN_LEN); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* Double Check to avoid basic fault injection */ + if (se_status == SE_SUCCESS) + { + /* Initialize the verification process */ + rv = C_VerifyInit(VerifySession, &cktest_ecdsa_256_mechanism, hECDSAKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* End-up verification process : control if the signature is correct */ + rv = C_Verify(VerifySession, (CK_BYTE_PTR)pPayload, payloadSize, (CK_BYTE_PTR)pSignature, SE_HEADER_SIGN_LEN); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + } + +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_CRYPTO_SCHEME */ + + /* Close the session */ + rv = C_CloseSession(VerifySession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* End-up the KMS service */ + C_Finalize(NULL) ; + + return se_status; + +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_kms.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_kms.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_kms.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_kms.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_kms.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_kms.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_kms.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_kms.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_loader.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_loader.c new file mode 100644 index 00000000..fb5936c9 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_loader.c @@ -0,0 +1,803 @@ +/** + ****************************************************************************** + * @file sfu_loader.c + * @author MCD Application Team + * @brief Secure Firmware Update LOADER module. + * This file provides set of firmware functions to manage SFU local + * loader functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "main.h" +#include "sfu_loader.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "sfu_com_loader.h" +#include "sfu_trace.h" +#include "se_interface_bootloader.h" /* for metadata authentication */ +#include "sfu_interface_crypto_scheme.h" +#include "sfu_fwimg_services.h" /* for version checking & to check if a valid FW is installed (the local + bootloader is a kind of "application" running in SB_SFU) */ +#include "app_sfu.h" + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + +/* Private variables ---------------------------------------------------------*/ +static uint8_t +fw_decrypted_chunk[SFU_COM_YMODEM_PACKET_1K_SIZE];/*!< Buffer used for decryption during reception process */ +static uint32_t m_uDwlAreaAddress = 0U; /*!< Address of to write in download area */ +static uint32_t m_uDwlAreaStart = 0U; /*!< Address of download area */ +static uint32_t m_uDwlAreaSize = 0U; /*!< Size of download area */ +static uint32_t m_uFileSizeYmodem = 0U; /*!< Ymodem file size being received */ +static uint32_t m_uNbrBlocksYmodem = 0U; /*!< Number of blocks being received via Ymodem*/ +static uint32_t m_uPacketsReceived = 0U; /*!< Number of packets received via Ymodem*/ +static uint32_t m_uDwlSlot = SLOT_INACTIVE; /*!< Dwl slot identification : to be intialialized after header check */ +static SFU_LOADER_StatusTypeDef m_LoaderStatus; /*!< Status of the loader */ + +/* Private function prototypes -----------------------------------------------*/ +static SFU_ErrorStatus SFU_LOADER_VerifyFwHeader(uint8_t *pBuffer); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Initialize the SFU LOADER. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LOADER_Init(void) +{ + /* + * ADD SRC CODE HERE + */ + + /* + * Sanity check to make sure that the local loader cannot read out of the buffer bounds + * when doing a length alignment before writing in FLASH. + */ + if (0U != (uint32_t)(sizeof(fw_decrypted_chunk) % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + /* The decrypt buffer must be a multiple of the FLASH write length */ + TRACE("\r\n= [FWIMG] Decrypt buffer size (%d) is not matching the FLASH constraints", sizeof(fw_decrypted_chunk)); + return SFU_ERROR; + } /* else the FW Header Length is fine with regards to FLASH constraints */ + + return SFU_SUCCESS; +} + +/** + * @brief DeInitialize the SFU LOADER. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LOADER_DeInit(void) +{ + /* + * ADD SRC CODE HERE + */ + return SFU_SUCCESS; +} + +/** + * @brief Download a new User Fw. + * Writes firmware received via Ymodem in FLASH. + * @param peSFU_LOADER_Status: SFU LOADER Status. + * This parameter can be a value of @ref SFU_LOADER_Status_Structure_definition. + * @param p_DwlSlot identification of the downloaded area + * @param p_Size Size of the downloaded image. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LOADER_DownloadNewUserFw(SFU_LOADER_StatusTypeDef *peSFU_LOADER_Status, uint32_t *pDwlSlot, + uint32_t *pSize) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_COM_YMODEM_StatusTypeDef e_com_status = SFU_COM_YMODEM_ERROR; + SE_StatusTypeDef e_se_status; + int32_t fw_tag_len = 0; + uint8_t fw_tag_output[SE_TAG_LEN]; + + /* Check the pointers allocation */ + if ((peSFU_LOADER_Status == NULL) || (pSize == NULL) || (pDwlSlot == NULL)) + { + return SFU_ERROR; + } + + /* Refresh Watchdog */ + (void) SFU_LL_SECU_IWDG_Refresh(); + + /* Transfer FW Image via YMODEM protocol */ + TRACE("\r\n\t File> Transfer> YMODEM> Send "); + + /* Initialize global variables to be used during the YMODEM process */ + m_uDwlAreaAddress = 0U; + m_uDwlAreaStart = 0U; + m_uDwlAreaSize = 0U; + m_uFileSizeYmodem = 0U; + m_uNbrBlocksYmodem = 0U; + m_uPacketsReceived = 0U; + m_uDwlSlot = SLOT_ACTIVE_1; + m_LoaderStatus = SFU_LOADER_ERR_COM; + + /* Receive the FW in RAM and write it in the Flash*/ + if (SFU_COM_YMODEM_Receive(&e_com_status, pSize) == SFU_SUCCESS) + { + if (*pSize > 0U) + { + /* File download correct*/ + m_LoaderStatus = SFU_LOADER_OK; + } + } + else + { + /* Nothing to do : m_LoaderStatus updated during during YModem process */ + } + + /* Provide slot information to the caller + m_uDwlSlot updated during VerifyFwHeader() except in case of bad formatted file + ==> m_uDwlSlot stick at SLOT_DWL_1 value if the header signature is not verified */ + *pDwlSlot = m_uDwlSlot; + + if (m_LoaderStatus == SFU_LOADER_OK) + { + /* End of decryption process */ + fw_tag_len = sizeof(fw_tag_output); + if (SE_Decrypt_Finish(&e_se_status, fw_tag_output, &fw_tag_len) != SE_SUCCESS) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + + } + else if (e_se_status != SE_OK) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + } + else + { + /* Nothing */ + } + } + + *peSFU_LOADER_Status = m_LoaderStatus; + if (m_LoaderStatus == SFU_LOADER_OK) + { + e_ret_status = SFU_SUCCESS; + } + return e_ret_status; +} + +/** + * @brief Ymodem Header Packet Transfer completed callback. + * @param uFileSize: Dimension of the file that will be received. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_YMODEM_HeaderPktRxCpltCallback(uint32_t uFileSize) +{ + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + + /*Filesize information is stored*/ + m_uFileSizeYmodem = uFileSize; + + /*Compute the number of blocks */ +#ifndef MINICOM_YMODEM + /* Teraterm sends 1kB YMODEM packets */ + m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (SFU_COM_YMODEM_PACKET_1K_SIZE - 1U)) / SFU_COM_YMODEM_PACKET_1K_SIZE; +#else + /* Minicom sends 128 bytes YMODEM packets */ + m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (SFU_COM_YMODEM_PACKET_SIZE - 1U)) / SFU_COM_YMODEM_PACKET_SIZE; +#endif /* MINICOM_YMODEM */ + + /* NOTE : delay inserted for Ymodem protocol*/ + HAL_Delay(1000U); + + return SFU_SUCCESS; +} + +/** + * @brief Ymodem Data Packet Transfer completed callback. + * @param pData: Pointer to the buffer. + * @param uSize: Packet dimension. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +#ifndef MINICOM_YMODEM +/* Teraterm variant of the YMODEM protocol: uses 1kB packets */ +SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) +{ + /* The local loader must make a copy of the Firmware metadata, + * because this memory area is not copied when calling the SE_Decrypt_Init() primitive. + * Hence we must make sure this memory area still contains the FW header when SE_Decrypt_Finish() is called. */ + static uint8_t fw_header[SE_FW_HEADER_TOT_LEN] __attribute__((aligned(8))); + /* Size of downloaded Image initialized with first packet (header) and checked along download process */ + static uint32_t m_uDwlImgSize = 0U; + + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + SFU_FLASH_StatusTypeDef x_flash_info; + uint32_t rx_size = uSize; + uint8_t *p_data = pData; + uint32_t uOldSize; + int32_t fw_decrypted_chunk_size; + SE_StatusTypeDef e_se_status = SE_KO; + + /* Check the pointers allocation */ + if (p_data == NULL) + { + return SFU_ERROR; + } + + /*Increase the number of received packets*/ + m_uPacketsReceived++; + + /* Last packet : size of data to write could be different than SFU_COM_YMODEM_PACKET_1K_SIZE */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + /*Extracting actual payload from last packet*/ + if (0U == (m_uFileSizeYmodem % SFU_COM_YMODEM_PACKET_1K_SIZE)) + { + /* The last packet must be fully considered */ + rx_size = SFU_COM_YMODEM_PACKET_1K_SIZE; + } + else + { + /* The last packet is not full, drop the extra bytes */ + rx_size = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / SFU_COM_YMODEM_PACKET_1K_SIZE) * + SFU_COM_YMODEM_PACKET_1K_SIZE); + } + } + + /* First packet : Contains the FW header (SE_FW_HEADER_TOT_LEN bytes length) which is not encrypted */ + if (m_uPacketsReceived == 1U) + { + + (void) memcpy(fw_header, p_data, SE_FW_HEADER_TOT_LEN); + + /* Verify header */ + e_ret_status = SFU_LOADER_VerifyFwHeader(p_data); + if (e_ret_status == SFU_SUCCESS) + { + m_uDwlAreaAddress = m_uDwlAreaStart; + + /* Downloaded Image size : Header size + Image size */ + m_uDwlImgSize = ((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header)->FwSize + SFU_IMG_IMAGE_OFFSET; + } + + /* Clear Download application area (including TRAILERS area) */ + if (e_ret_status == SFU_SUCCESS) + { + if (SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) m_uDwlAreaAddress, SLOT_SIZE(m_uDwlSlot)) != + SFU_SUCCESS) + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + + /* Initialize decryption process */ + if (e_ret_status == SFU_SUCCESS) + { + if (SE_Decrypt_Init(&e_se_status, (SE_FwRawHeaderTypeDef *)fw_header, SE_FW_IMAGE_COMPLETE) != SE_SUCCESS) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else if (e_se_status != SE_OK) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else + { + /* Store FW image header in Flash */ + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, p_data, SE_FW_HEADER_TOT_LEN) == + SFU_SUCCESS) + { + /* Shift the DWL area pointer */ + m_uDwlAreaAddress += SE_FW_HEADER_TOT_LEN; + rx_size -= SE_FW_HEADER_TOT_LEN; + p_data += SE_FW_HEADER_TOT_LEN; + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + } + } + + if (e_ret_status == SFU_SUCCESS) + { + /* if the data is part of SFU_IMG_IMAGE_OFFSET nothing to do ==> padding */ + if (m_uDwlAreaAddress < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) + { + /* all the data are located inside SFU_IMG_IMAGE_OFFSET : nothing to do ==> full padding */ + if ((m_uDwlAreaAddress + rx_size) < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) + { + m_uDwlAreaAddress += rx_size; + p_data += rx_size; + rx_size = 0U; + } + /* part of the data is inside SFU_IMG_IMAGE_OFFSET ==> remaining bytes to be deccrypted */ + else + { + rx_size -= (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); + p_data += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); + m_uDwlAreaAddress += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); + } + } + + /* remaining bytes to decrypt ? */ + if (rx_size != 0U) + { + fw_decrypted_chunk_size = rx_size; + if ((e_ret_status == SFU_SUCCESS) + && (SE_Decrypt_Append(&e_se_status, p_data, rx_size, fw_decrypted_chunk, &fw_decrypted_chunk_size) + != SE_SUCCESS)) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else if ((e_se_status != SE_OK) || (fw_decrypted_chunk_size != rx_size)) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else + { + /*Nothing */ + } + } + } + + + if (e_ret_status == SFU_SUCCESS) + { + /* Check size to avoid writing beyond DWL image size */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlImgSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Set dimension to the appropriate length for FLASH programming. + * Example: 64-bit length for L4. + */ + if ((rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t)) != 0U) + { + /* By construction, the length of the buffer (fw_decrypted_chunk or p_data) must be a multiple of + sizeof(SFU_IMG_write_t) to avoid reading out of the buffer */ + uOldSize = rx_size; + rx_size = rx_size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - (rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); + while (uOldSize < rx_size) + { + fw_decrypted_chunk[uOldSize] = 0xFF; + uOldSize++; + } + } + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Check size to avoid writing beyond DWL area */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlAreaSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + } + + /* Write Data in Flash */ + if (e_ret_status == SFU_SUCCESS) + { + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, fw_decrypted_chunk, rx_size) == SFU_SUCCESS) + { + m_uDwlAreaAddress += (rx_size); + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + + + /* Last packet : reset m_uPacketsReceived */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + m_uPacketsReceived = 0U; + } + + /* Reset data counters in case of error */ + if (e_ret_status == SFU_ERROR) + { + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + } + + return e_ret_status; +} +#else /* MINICOM_YMODEM */ +/* Minicom variant of the YMODEM protocol: uses 128B packets */ +SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) +{ + /* The local loader must make a copy of the Firmware metadata, + * because this memory area is not copied when calling the SE_Decrypt_Init() primitive. + * Hence we must make sure this memory area still contains the FW header when SE_Decrypt_Finish() is called. */ + static uint8_t fw_header[SE_FW_HEADER_TOT_LEN] __attribute__((aligned(8))); + /* Size of downloaded Image initialized with first packet (header) and checked along download process */ + static uint32_t m_uDwlImgSize = 0U; + + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + SFU_FLASH_StatusTypeDef x_flash_info; + uint32_t rx_size = uSize; + uint8_t *p_data = pData; + uint32_t uOldSize; + int32_t fw_decrypted_chunk_size; + SE_StatusTypeDef e_se_status = SE_KO; + + /* Check the pointers allocation */ + if (p_data == NULL) + { + return SFU_ERROR; + } + + /*Increase the number of received packets*/ + m_uPacketsReceived++; + + /* Last packet : size of data to write could be different than SFU_COM_YMODEM_PACKET_1K_SIZE */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + /*Extracting actual payload from last packet: minicom works by default with 128B packets */ + if (0 == (m_uFileSizeYmodem % SFU_COM_YMODEM_PACKET_SIZE)) + { + /* The last packet must be fully considered */ + rx_size = SFU_COM_YMODEM_PACKET_SIZE; + } + else + { + /* The last packet is not full, drop the extra bytes: minicom works by default with 128B packets */ + rx_size = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / SFU_COM_YMODEM_PACKET_SIZE) * + SFU_COM_YMODEM_PACKET_SIZE); + } + } + + + /* + * Minicom splits the header of 192 bytes on 2 packets of 128 bytes. + */ + + /* First packet : Contains the first 128B of FW header (out of SE_FW_HEADER_TOT_LEN bytes length) which is + not encrypted */ + if (1 == m_uPacketsReceived) + { + /* First packet: beginning of header */ + if (SFU_COM_YMODEM_PACKET_SIZE == rx_size) + { + /* Copy the beginning of the header */ + memcpy(fw_header, p_data, rx_size); + rx_size = 0U; /* nothing more to do */ + } + else + { + /* Unexpected case */ + e_ret_status = SFU_ERROR; + } + } + else if (2U == m_uPacketsReceived) + { + /* Second packet: end of header (64 bytes) */ + memcpy(fw_header + SFU_COM_YMODEM_PACKET_SIZE, p_data, 64U); + rx_size -= 64U; + p_data += 64U; + + /* Verify header */ + e_ret_status = SFU_LOADER_VerifyFwHeader(fw_header); + + if (e_ret_status == SFU_SUCCESS) + { + m_uDwlAreaAddress = m_uDwlAreaStart; + /* Downloaded Image size : Header size + Image size */ + m_uDwlImgSize = ((SE_FwRawHeaderTypeDef *)fw_header)->FwSize + SFU_IMG_IMAGE_OFFSET; + + /* Clear Download application area (including TRAILERS area) */ + if ((e_ret_status == SFU_SUCCESS) + && (SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) m_uDwlAreaAddress, SLOT_SIZE(m_uDwlSlot)) != + SFU_SUCCESS)) + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Initialize decryption process */ + if ((e_ret_status == SFU_SUCCESS) + && (SE_Decrypt_Init(&e_se_status, (SE_FwRawHeaderTypeDef *)fw_header, SE_FW_IMAGE_COMPLETE) != SE_SUCCESS)) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else if (e_se_status != SE_OK) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else + { + /* Write the FW header (SE_FW_HEADER_TOT_LEN bytes length) at start of DWL area */ + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, fw_header, SE_FW_HEADER_TOT_LEN) + == SFU_SUCCESS) + { + /* Shift the DWL area pointer */ + m_uDwlAreaAddress += SE_FW_HEADER_TOT_LEN; + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + } + /* The remaining 64 bytes of data must be handled : standard processing */ + } + } + /* + * Else: standard packet data processing based on rx_size (full packet or the last 64 bytes of the 2nd packet) + */ + if (e_ret_status == SFU_SUCCESS) + { + /* + * if the data is part of SFU_IMG_IMAGE_OFFSET nothing to do ==> padding + */ + if (m_uDwlAreaAddress < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) + { + if ((m_uDwlAreaAddress + rx_size) < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) + { + /* all the data are located inside SFU_IMG_IMAGE_OFFSET : nothing to do ==> full padding */ + m_uDwlAreaAddress += rx_size; + p_data += rx_size; + rx_size = 0U; + } + else + { + /* part of the data is inside SFU_IMG_IMAGE_OFFSET ==> remaining bytes to be decrypted */ + rx_size -= (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); + p_data += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); + m_uDwlAreaAddress += (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET - m_uDwlAreaAddress); + } + } + + /* remaining bytes to decrypt ? */ + if (rx_size != 0) + { + fw_decrypted_chunk_size = rx_size; + if ((e_ret_status == SFU_SUCCESS) + && (SE_Decrypt_Append(&e_se_status, p_data, rx_size, fw_decrypted_chunk, &fw_decrypted_chunk_size) + != SE_SUCCESS)) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else if ((e_se_status != SE_OK) || (fw_decrypted_chunk_size != rx_size)) + { + m_LoaderStatus = SFU_LOADER_ERR_CRYPTO; + e_ret_status = SFU_ERROR; + } + else + { + /*Nothing */ + } + + /* Check size to avoid writing beyond DWL image size */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlImgSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + + /* Set dimension to the appropriate length for FLASH programming. + * Example: 64-bit length for L4. + */ + if ((rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t)) != 0) + { + /* By construction, the length of the buffer (fw_decrypted_chunk or p_data) must be a multiple of + sizeof(SFU_IMG_write_t) to avoid reading out of the buffer */ + uOldSize = rx_size; + rx_size = rx_size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - + (rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); + while (uOldSize < rx_size) + { + p_data[uOldSize] = 0xFF; + uOldSize++; + } + } + + /* Check size to avoid writing beyond DWL area */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlAreaSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + + /* Write Data in Flash */ + if (e_ret_status == SFU_SUCCESS) + { + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, fw_decrypted_chunk, rx_size) == SFU_SUCCESS) + { + m_uDwlAreaAddress += (rx_size); + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + } + } + + + /* Last packet : reset m_uPacketsReceived */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + m_uPacketsReceived = 0U; + } + + /* Reset data counters in case of error */ + if (e_ret_status == SFU_ERROR) + { + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + } + + return e_ret_status; +} +#endif /* MINICOM_YMODEM */ + + +/** + * @brief Verifies the Raw Fw Header received. It checks if the header is + * authentic and if the fields are ok with the device (e.g. size and version). + * @note Please note that when the new image is installed, this metadata is checked + * by @ref SFU_IMG_CheckCandidateVersion. + * @param peSFU_LOADER_Status: SFU LOADER Status. + * This parameter can be a value of @ref SFU_LOADER_Status_Structure_definition. + * @param pBuffer: pointer to header Buffer. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ + +/* anti-rollback mechanism is tested twice to avoid basic hardware attack + ==> compiler optimization is disabled for this reason */ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O0"))) +#endif /* __ICCARM__ */ + +static SFU_ErrorStatus SFU_LOADER_VerifyFwHeader(uint8_t *pBuffer) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + SE_FwRawHeaderTypeDef *p_x_fw_raw_header; + SFU_FwImageFlashTypeDef fw_image_flash_data; + uint16_t cur_ver; + uint16_t verif_ver; + uint32_t active_slot; + + /*Parse the received buffer*/ + p_x_fw_raw_header = (SE_FwRawHeaderTypeDef *)(uint32_t)pBuffer; + /*Check if the received header packet is authentic*/ + if (SE_VerifyHeaderSignature(&e_se_status, p_x_fw_raw_header) != SE_ERROR) + { + active_slot = SFU_IMG_GetFwImageSlot(p_x_fw_raw_header); + /* + * 1 slot per image configuration. Identify the download area. + * It will be based on SFU magic : + * - dwl slot is the active_slot if configured. + * - else : SLOT_ACTIVE_1 + */ + m_uDwlSlot = active_slot; + if (SLOT_SIZE(m_uDwlSlot) == 1U) + { + m_uDwlSlot = SLOT_ACTIVE_1; + } + SFU_IMG_GetDownloadAreaInfo(m_uDwlSlot, &fw_image_flash_data); + + /* Assign the download flash address to be used during the YMODEM process */ + m_uDwlAreaStart = fw_image_flash_data.DownloadAddr; + m_uDwlAreaSize = fw_image_flash_data.MaxSizeInBytes; + + /* + * Check if the version is allowed + * ==> SFU_IMG_GetActiveFwVersion() returns 0 if the header of active firmware is not valid + */ + cur_ver = SFU_IMG_GetActiveFwVersion(active_slot); + if (SFU_IMG_CheckFwVersion(active_slot, cur_ver, p_x_fw_raw_header->FwVersion) == SFU_SUCCESS) + { + /* + * Check length : Let's make sure the Firmware image can be written in the destination slot. + */ + if (p_x_fw_raw_header->FwSize > (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) + { + /* The firmware cannot be written in dwl slot */ + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + } + else + { + /* Installation authorized */ + e_ret_status = SFU_SUCCESS; + } + } + else + { + /* The installation is forbidden */ + TRACE("\r\n Anti-rollback: candidate version(%d) rejected | current version(%d) , min.version(%d) !", + p_x_fw_raw_header->FwVersion, cur_ver, SFU_FW_VERSION_START_NUM); + m_LoaderStatus = SFU_LOADER_ERR_FW_VERSION; + } + + + /* + * Control of version and length is done twice to avoid basic hardware attack + * This more important for the 1 image configuration as the installation is done during the download procedure + * For the 2 images configuration anti-rollback will be checked again during installation process + */ + verif_ver = SFU_IMG_GetActiveFwVersion(active_slot); + if (SFU_IMG_CheckFwVersion(active_slot, verif_ver, p_x_fw_raw_header->FwVersion) == SFU_SUCCESS) + { + /* + * Check length : Let's make sure the Firmware image can be written in the destination slot. + */ + if (p_x_fw_raw_header->FwSize > (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) + { + /* The firmware cannot be written in dwl slot */ + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + } + else + { + /* Installation authorized */ + e_ret_status = SFU_SUCCESS; + } + } + else + { + /* The installation is forbidden */ + TRACE("\r\n Anti-rollback: candidate version(%d) rejected | current version(%d) , min.version(%d) !", + p_x_fw_raw_header->FwVersion, verif_ver, SFU_FW_VERSION_START_NUM); + m_LoaderStatus = SFU_LOADER_ERR_FW_VERSION; + } + } + else + { + /* Header authentication failure */ + m_LoaderStatus = SFU_LOADER_ERR_AUTH_FAILED; + } + + return e_ret_status; +} + +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_loader.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_loader.h new file mode 100644 index 00000000..7467d978 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_loader.h @@ -0,0 +1,63 @@ +/** + ****************************************************************************** + * @file sfu_loader.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update local + * loader. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOADER_H +#define SFU_LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "se_def.h" +#include "sfu_def.h" +#include "sfu_new_image.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * Local loader status Type Definition + */ +typedef enum +{ + SFU_LOADER_OK = 0x00U, + SFU_LOADER_ERR_COM = 0x01U, + SFU_LOADER_ERR_AUTH_FAILED = 0x02U, + SFU_LOADER_ERR_FW_LENGTH = 0x03U, + SFU_LOADER_ERR_FW_VERSION = 0x04U, + SFU_LOADER_ERR_FLASH = 0x05U, + SFU_LOADER_ERR_CRYPTO = 0x06U +} SFU_LOADER_StatusTypeDef; + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LOADER_Init(void); +SFU_ErrorStatus SFU_LOADER_DeInit(void); +SFU_ErrorStatus SFU_LOADER_DownloadNewUserFw(SFU_LOADER_StatusTypeDef *peSFU_LOADER_Status, uint32_t *p_DwlSlot, + uint32_t *p_Size); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOADER_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_new_image.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_new_image.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_new_image.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_new_image.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_new_image.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_new_image.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_new_image.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_new_image.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_test.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_test.c new file mode 100644 index 00000000..213ef868 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_test.c @@ -0,0 +1,328 @@ +/** + ****************************************************************************** + * @file sfu_test.c + * @author MCD Application Team + * @brief Test Protections module. + * This file provides set of firmware functions to manage Test Protections + * functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_test.h" +#include "main.h" +#include "sfu_trace.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "sfu_low_level.h" +#include "string.h" /* required for strncmp */ + +#if defined(SFU_TEST_PROTECTION) + +extern RTC_HandleTypeDef RtcHandle; + +/* Private defines -----------------------------------------------------------*/ + +/* Automatic tests : list of tests (Address, Message, Operation */ +/* Flash programming by 64 bits */ +#define SHIFT_FLASH_WRITE (8U-1U) + +/* Private variables ---------------------------------------------------------*/ +static ProtectionTest_t aProtectTests[] = +{ +#ifdef SFU_MPU_PROTECT_ENABLE + {SFU_RAM_BASE, "MPU SRAM1 start add", TEST_EXECUTE}, + {SFU_RAM_END - 3U, "MPU SRAM1 end add", TEST_EXECUTE}, /* -3 : previous 32 bits for execute test */ + {PERIPH_BASE, "Peripheral base add", TEST_EXECUTE}, + {((uint32_t)0x5FFFFFFF - 3U), "Peripheral end address", TEST_EXECUTE}, /* -3 : previous 32 bits for execute test */ + /* READ_FLASH is possible as we are privileged when there is no MPU isolation but WRITE_FLASH must fail */ + {INTVECT_START, "Init. Vector", TEST_WRITE_FLASH}, + {SLOT_ACTIVE_1_START, "MPU code active slot1 begin add", TEST_EXECUTE}, + {SLOT_ACTIVE_1_END - 3U, "MPU code active1 slot end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SLOT_ACTIVE_2_START, "MPU code active slot2 begin add", TEST_EXECUTE}, + {SLOT_ACTIVE_2_END - 3U, "MPU code active slot2 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SLOT_ACTIVE_3_START, "MPU code active slot3 begin add", TEST_EXECUTE}, + {SLOT_ACTIVE_3_END - 3U, "MPU code active slot3 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ +#endif /* SFU_MPU_PROTECT_ENABLE */ +#ifdef SFU_WRP_PROTECT_ENABLE + {INTVECT_START, "WRP start add", TEST_WRITE_FLASH}, + {SFU_ROM_ADDR_END - SHIFT_FLASH_WRITE, "WRP end add", TEST_WRITE_FLASH}, /* -7 : alignment for 64bits writing test */ + {SB_REGION_ROM_START, "WRP internal (SB) add", TEST_ERASE_FLASH}, +#endif /* SFU_WRP_PROTECT_ENABLE */ +#ifdef SFU_PCROP_PROTECT_ENABLE + {SE_KEY_REGION_ROM_START, "PCROP start add", TEST_WRITE_FLASH}, + {SE_KEY_REGION_ROM_END - SHIFT_FLASH_WRITE, "PCROP end add", TEST_WRITE_FLASH}, /* -7 : alignment for 64bits + writing test */ + {SE_KEY_REGION_ROM_START, "PCROP start add", TEST_READ_FLASH}, + {SE_KEY_REGION_ROM_END, "PCROP end add", TEST_READ_FLASH}, +#endif /* SFU_PCROP_PROTECT_ENABLE */ +#if defined(TEST_ISOLATION) + {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_WRITE_FLASH}, /* WRP protection applies */ + {SE_CODE_REGION_ROM_END - SHIFT_FLASH_WRITE, "Isolated code end add", TEST_WRITE_FLASH},/* -7 : alignment for + 64bits writing test + WRP protection applies */ + {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_READ_FLASH}, + {SE_CODE_REGION_ROM_END, "Isolated code end add", TEST_READ_FLASH}, + {SE_STARTUP_REGION_ROM_START + 1U, "Isolated startup add", TEST_EXECUTE}, /* +1 : contains the SE startup code + that initializes all the variables in the binary. */ + {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_EXECUTE}, + {SE_CODE_REGION_ROM_END - 3U, "Isolated code end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SE_REGION_RAM_START, "Isolated Vdata add", TEST_WRITE_RAM}, + {SE_REGION_RAM_END - 3U, "Isolated Vdata add", TEST_WRITE_RAM}, /* -3 : alignment for 32bits writing test */ + {SE_REGION_RAM_START, "Isolated Vdata add", TEST_READ_RAM}, + {SE_REGION_RAM_END, "Isolated Vdata add", TEST_READ_RAM}, + {SE_REGION_RAM_START, "Isolated Vdata add", TEST_EXECUTE}, + {SE_REGION_RAM_END - 3U, "Isolated Vdata add", TEST_EXECUTE}, /* -3 : alignment for 32bits writing test */ + {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, + /* -8 : previous 64 bits for writing test */ + {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits + for reading test */ + {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits + for execute test */ + {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, + /* -8 : previous 64 bits for writing test */ + {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits + for reading test */ + {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits + for execute test */ + {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, + /* -8 : previous 64 bits for writing test */ + {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits + for reading test */ + {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits + for execute test */ +#endif /* TEST_ISOLATION */ +#ifdef SFU_MPU_PROTECT_ENABLE + /* Testing the MPU protection of the OBs */ + /* + * WL55JC + * 0x1FFF 7800 Reserved user option bytes & RDP (USER & RDP) + * 0x1FFF 7818 Reserved Write protection 1A + * 0x1FFF 7820 Reserved Write protection 1B + */ + {(uint32_t)0x1FFF7800, "OBs @ 0x1FFF7800", TEST_WRITE_FLASH}, + {(uint32_t)0x1FFF7818, "OBs @ 0x1FFF7818", TEST_WRITE_FLASH}, + {(uint32_t)0x1FFF7820, "OBs @ 0x1FFF7820", TEST_WRITE_FLASH}, +#endif /* SFU_MPU_PROTECT_ENABLE */ + {0xAAAAAAAA, "Execution successful", TEST_END}, +}; + + +/* Automatic test : list of operation */ +uint8_t aTestOperation[][20] = +{ + "write 8 bytes", + "read 1 byte", + "erase 512 bytes", + "write 4 bytes", + "read 1 byte", + "execute", + "end" +}; + +/* Private function prototypes -----------------------------------------------*/ +static void SFU_TEST_Protection(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Automatic test of PCROP/WRP/FWALL/MPU protections + * @param None. + * @retval None. + */ +static void SFU_TEST_Protection(void) +{ + uint32_t test_idx; + uint32_t flashErrCode = 0; + uint64_t pattern = 0U; + uint32_t page_error = 0U; + FLASH_EraseInitTypeDef p_erase_init; + TestStatus status = TEST_IN_PROGRESS; + __IO uint8_t tmp; + void (*func)(void); + + /* + * Now checking the security + * We will try to access protected @ and run protected code. + * Each time a a flash error will be raised or a reset will be generated by IP protection. + * At next boot we read the backup register to check the next @ until all addresses have been verified. + * WatchDog should be disabled : while(1) loop in case HardFault when trying to execute code @ address protected by + * FWALL/Code Isolation + */ + + do + { + /* slow down execution */ + HAL_Delay(100); + + /* Increment test number for next execution */ + test_idx = HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR1); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, (test_idx + 1)); + printf("\r\n= [TEST] %s @ %s %08x", aTestOperation[aProtectTests[test_idx].type], aProtectTests[test_idx].msg, + aProtectTests[test_idx].address); + + /* Remove test for slots not configured (taking into accounbt SFU_IMG_IMAGE_OFFSET) */ + if ((aProtectTests[test_idx].address != 0U) && (aProtectTests[test_idx].address < 0xFFFFFF00U) + && (aProtectTests[test_idx].address > 0x00000FFFU)) + { + switch (aProtectTests[test_idx].type) + { + /* Trying to write 64bits in FLASH : WRP flag is set for WRP or PCROP protected area + or reset generated if under FWALL or MPU protection */ + case TEST_WRITE_FLASH : + HAL_FLASH_Unlock(); + HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, aProtectTests[test_idx].address, pattern); + HAL_FLASH_Lock(); + flashErrCode = HAL_FLASH_GetError(); + printf("\r\nflash error code: %x", flashErrCode); + if ((flashErrCode & HAL_FLASH_ERROR_WRP) == 0U) + { + status = TEST_ERROR; + } + + /* + * OBs protection test: MPU generates a MEMORY FAULT and a RESET + * So the test is FAILED if we reach this line + */ + if (0 == strncmp("OBs @", (const char *)aProtectTests[test_idx].msg, 5)) + { + status = TEST_ERROR; + } + /* else not an OB protection test so probably not an error */ + break; + + /* Trying to read in FLASH : RDP set in case of PCROP protected area + or reset generated if under FWALL or MPU protection */ + case TEST_READ_FLASH : + tmp = *(uint8_t *)(aProtectTests[test_idx].address); + HAL_Delay(1); /* ensure Flag is set */ + /* + * When Isolation activated : RESET should be generated + * So the test is FAILED if we reach this line + */ + if (0 == strncmp("Isolated", (const char *)aProtectTests[test_idx].msg, 8)) + { + status = TEST_ERROR; + } + + break; + + /* Trying to erase 512 bytes in FLASH : WRP flag set for WRP or PCROP protected area + or reset generated if under FWALL or MPU protection */ + case TEST_ERASE_FLASH : + HAL_FLASH_Unlock(); + p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + p_erase_init.Page = SFU_LL_FLASH_GetPage(aProtectTests[test_idx].address); + p_erase_init.NbPages = 1; + HAL_FLASHEx_Erase(&p_erase_init, &page_error); + HAL_FLASH_Lock(); + if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) == 0U) + { + status = TEST_ERROR; + } + break; + + /* Trying to write in RAM : reset generated if under FWALL or MPU protection */ + case TEST_WRITE_RAM : + *(uint32_t *)aProtectTests[test_idx].address = 0x00000000; + status = TEST_ERROR; + break; + + /* Trying to read in RAM : reset generated if under FWALL or MPU protection */ + case TEST_READ_RAM : + tmp = *(uint8_t *)aProtectTests[test_idx].address; + printf(" value : %d ", tmp); + status = TEST_ERROR; + break; + + /* Tryning to execute code : reset generated if under FWALL or MPU protection */ + case TEST_EXECUTE : + func = (void(*)(void))(aProtectTests[test_idx].address); + func(); + status = TEST_ERROR; + break; + + /* End of execution */ + case TEST_END : + status = TEST_COMPLETED; + break; + + default : + break; + } + } + } while (status == TEST_IN_PROGRESS) ; + + if (status == TEST_ERROR) + { + SFU_TEST_Error(); + } + else if (status == TEST_COMPLETED) + { + /* reset for next run (need a RESET of the platform to restart a session) */ + printf("\b\b\b\b\b\b\b\b"); + printf("\r\nYou can RESET the platform to restart the tests.\r\n"); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_DONE); /* no more test in progress */ + } +} + +/** + * @brief Initialization of backup register and start test + * @param None. + * @retval None. + */ +void SFU_TEST_Init(void) +{ + /* Use register DR0 to know which if the test sequence is in progress or done */ + /* Use register DR1 to know which test to run after a reset */ + + if (MAGIC_TEST_DONE == HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0)) /* Test done */ + { + return; + } + else if (MAGIC_TEST_INIT != HAL_RTCEx_BKUPRead(&RtcHandle, + RTC_BKP_DR0)) /* Test not done nor in progress: Init magic (DR0) and + reset test index (DR1) */ + { + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_INIT); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, 0x0000); + } + + /* Start test */ + SFU_TEST_Protection(); +} + +/** + * @brief Reset backup register to be able to execute a new test sequence + * @param None. + * @retval None. + */ +void SFU_TEST_Reset(void) +{ + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_INIT); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, 0x0000); +} + +/** + * @brief Error detected during test sequence + * @param None. + * @retval None. + */ +void SFU_TEST_Error(void) +{ + printf(" ===> KO!!!!!"); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_DONE); +} + +#endif /* SFU_TEST_PROTECTION */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_test.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_test.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/BFU/App/sfu_test.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_test.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_trace.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_trace.h new file mode 100644 index 00000000..cf6d3387 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/App/sfu_trace.h @@ -0,0 +1,80 @@ +/** + ****************************************************************************** + * @file sfu_trace.h + * @author MCD Application Team + * @brief This file contains definitions for SFU_TRACE functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_TRACE_H +#define SFU_TRACE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "app_sfu.h" +#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) +#include "sfu_com_trace.h" +#endif /* defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) */ + +/* External variables --------------------------------------------------------*/ +/** + * This variable indicates if at boot-up the FW presence check has already been performed or not: + * \li It is reset when the FW status has already been checked once and no FW is present + * \li (see @ref SFU_BOOT_SM_CheckUserFwStatus) + * \li It is used to display some messages only once in the teraterm console + * \li It is used to determine if the user button must be pressed before waiting for a local download to start + * \li This is used at LocalDownload and CheckUserFwStatus stages. + */ +extern uint8_t initialDeviceStatusCheck; /* used also in sfu_fwimg_swap.c */ + +/* Exported macros -----------------------------------------------------------*/ +#ifdef SFU_DEBUG_MODE +#define TRACE_IRQ(pbuffer) (void) SFU_COM_Serial_PutString(pbuffer); /* Printf is not used inside interrupt to avoid + faults. printf is not rieentrant */ +#define TRACE (void) printf +#else +#define TRACE(...) +#define TRACE_IRQ(pbuffer) +#endif /* SFU_DEBUG_MODE */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_TRACE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level.c new file mode 100644 index 00000000..e637a536 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level.c @@ -0,0 +1,530 @@ +/** + ****************************************************************************** + * @file sfu_low_level.c + * @author MCD Application Team + * @brief SFU Low Level Interface module + * This file provides set of firmware functions to manage SFU low level + * interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_LOW_LEVEL_C + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level.h" +#include "sfu_trace.h" + +#ifndef SFU_TAMPER_PROTECT_ENABLE +extern RTC_HandleTypeDef RtcHandle; +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + +/* Private variables ---------------------------------------------------------*/ +static UART_HandleTypeDef UartHandle; +static CRC_HandleTypeDef CrcHandle; + +/* Private function prototypes -----------------------------------------------*/ +static void SFU_LL_Error_Handler(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Initialize SFU Interface. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Initialize CRC */ + e_ret_status = SFU_LL_CRC_Init(); + + return e_ret_status; +} + +/** + * @brief DeInitialize SFU Interface. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_DeInit(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* ADD SRC CODE HERE + ... + */ + return e_ret_status; +} + +/** + * @brief SFU IF CRC Init. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_CRC_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Configure the peripheral clock */ + __HAL_RCC_CRC_CLK_ENABLE(); + + + /* Configure CRC with default polynomial - standard configuration */ + e_ret_status = SFU_LL_CRC_Config(SFU_CRC_CONFIG_DEFAULT); + + return e_ret_status; +} + +/** + * @brief SFU IF CRC Configuration. + * @param eCRCConfg: SFU_CRC_ConfigTypeDef. + * This parameter can be a value of @ref SFU_CRC_ConfigTypeDef. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_CRC_Config(SFU_CRC_ConfigTypeDef eCRCConfg) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + + /* Check the parameters */ + assert_param(IS_SFU_CRC_CONF(eCRCConfg)); + + /* Switch to the selected configuration */ + CrcHandle.Instance = CRC; + + /* The input data are not inverted */ + CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + + /* The output data are not inverted */ + CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + + switch (eCRCConfg) + { + case SFU_CRC_CONFIG_DEFAULT: + /* The Default polynomial is used */ + CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + /* The default init value is used */ + CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + /* The input data are 32-bit long words */ + CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS; + /* Valid parameter*/ + e_ret_status = SFU_SUCCESS; + break; + + case SFU_CRC_CONFIG_16BIT: + /* The CRC-16-CCIT polynomial is used */ + CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; + CrcHandle.Init.GeneratingPolynomial = 0x1021U; + CrcHandle.Init.CRCLength = CRC_POLYLENGTH_16B; + /* The zero init value is used */ + CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; + CrcHandle.Init.InitValue = 0U; + /* The input data are 8-bit long */ + CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + /* Valid parameter*/ + e_ret_status = SFU_SUCCESS; + break; + + default: + /* Invalid parameter */ + e_ret_status = SFU_ERROR; + break; + } + + /* Proceed to CRC Init (Correct Parameters) */ + if (e_ret_status == SFU_SUCCESS) + { + if (HAL_CRC_Init(&CrcHandle) != HAL_OK) + { + e_ret_status = SFU_ERROR; + } + } + + return e_ret_status; +} + + +/** + * @brief SFU IF CRC Calculate. + * @param pBuffer: pointer to data buffer. + * @param BufferLength: buffer length in bytes. + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +uint32_t SFU_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t BufferLength) +{ + return HAL_CRC_Calculate(&CrcHandle, pBuffer, BufferLength); +} + +/** + * @brief SFU UART Init. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_UART_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/ + /* USART configured as follow: + - BaudRate = 115200 baud + - Word Length = 8 Bits + - One Stop Bit + - No parity + - Hardware flow control disabled (RTS and CTS signals) + - Receive and transmit enabled + */ + UartHandle.Instance = SFU_UART; + UartHandle.Init.BaudRate = 115200U; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_RX | UART_MODE_TX; + UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; + UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; + if (HAL_UART_Init(&UartHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; + +} + +/** + * @brief SFU IF UART DeInit. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_UART_DeInit(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* + * ADD SRC CODE HERE + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; + +} + +/** + * @brief SFU IF Write data (send). + * @param pData: pointer to the 128bit data to write. + * @param DataLength: pointer to the 128bit data to write. + * @param pData: pointer to the 128bit data to write. + * @param Timeout: Timeout duration. + * @retval status of the write operation + * SFU_ERROR : if the write operation is not performed + * SFU_SUCCESS : if the write operation is successfully performed + */ +SFU_ErrorStatus SFU_LL_UART_Transmit(uint8_t *pData, uint16_t DataLength, uint32_t Timeout) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check the pointers allocation */ + if (pData == NULL) + { + return SFU_ERROR; + } + + if (HAL_UART_Transmit(&UartHandle, (uint8_t *)pData, DataLength, Timeout) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief SFU IF Read data (receive). + * @param pData: pointer to the 128bit data where to store the received data. + * @param DataLength: the length of the data to be read in bytes. + * @param Timeout: Timeout duration. + * @retval status of the read operation + * SFU_ERROR : if the read operation is not performed + * SFU_SUCCESS : if the read operation is successfully performed + */ +SFU_ErrorStatus SFU_LL_UART_Receive(uint8_t *pData, uint16_t DataLength, uint32_t Timeout) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check the pointers allocation */ + if (pData == NULL) + { + return SFU_ERROR; + } + + if (HAL_UART_Receive(&UartHandle, (uint8_t *)pData, DataLength, Timeout) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief SFU HAL IF Flush. + * @param None. + * @retval status of the operation. + */ +SFU_ErrorStatus SFU_LL_UART_Flush(void) +{ + /* Clean the input path */ + __HAL_UART_FLUSH_DRREGISTER(&UartHandle); + + return SFU_SUCCESS; +} + +#ifndef SFU_TAMPER_PROTECT_ENABLE +/** + * @brief SFU IF RTC Init. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_RTC_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Configure RTC prescaler and RTC data registers */ + /* RTC configured as follows: + - Hour Format = Format 24 + - Asynch Prediv = Value according to source clock + - Synch Prediv = Value according to source clock + - OutPut = Output Disable + - OutPutPolarity = High Polarity + - OutPutType = Open Drain */ + RtcHandle.Instance = RTC; + RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; + RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; + RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; + RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; + RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + + if (HAL_RTC_Init(&RtcHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief SFU IF RTC DeInit. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_RTC_DeInit(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* + * ADD SRC CODE HERE + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; + +} + +#endif /*SFU_TAMPER_PROTECT_ENABLE*/ + +/** + * @brief SFU IF RTC MSP Initialization + * This function configures the hardware resources used in this example + * @param hrtc: RTC handle pointer. + * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select + * the RTC clock source; in this case the Backup domain will be reset in + * order to modify the RTC Clock source, as consequence RTC registers (including + * the backup registers) and RCC_BDCR register are set to their reset values. + * @retval None + */ +void SFU_LL_RTC_MspInit(RTC_HandleTypeDef *hrtc) +{ + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + UNUSED(hrtc); + /*-1- Enables access to the backup domain */ + /* To enable access on RTC registers */ + + HAL_PWR_EnableBkUpAccess(); + + /*-2- Configure LSE/LSI as RTC clock source */ +#ifdef RTC_CLOCK_SOURCE_LSE + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_OFF; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } +#elif defined (RTC_CLOCK_SOURCE_LSI) + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.LSIDiv = LL_RCC_LSI_PREDIV_1; + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } +#else +#error Please select the RTC Clock source inside the main.h file +#endif /*RTC_CLOCK_SOURCE_LSE*/ + + /*-3- Enable RTC peripheral Clocks */ + /* Enable RTC Clock */ + __HAL_RCC_RTC_ENABLE(); + + /* Enable RTC APB clock */ + __HAL_RCC_RTCAPB_CLK_ENABLE(); +#ifdef SFU_TAMPER_PROTECT_ENABLE + /*-4- Configure the NVIC for RTC Tamper */ + HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, 0x0FU, 0U); + HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); +#endif /* SFU_TAMPER_PROTECT_ENABLE */ +} + +/** + * @brief RTC MSP De-Initialization + * This function frees the hardware resources used in in SFU application: + * - Disable the Peripheral's clock + * @param hrtc: RTC handle pointer + * @retval None + */ +void SFU_LL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc) +{ + UNUSED(hrtc); + + __HAL_RCC_RTC_DISABLE(); + + /* Disable RTC APB clock */ + __HAL_RCC_RTCAPB_CLK_DISABLE(); +} + +/** + * @brief UART MSP Initialization + * This function configures the hardware resources used in SFU application. + * @param huart: UART handle pointer + * @retval None + */ +void SFU_LL_UART_MspInit(UART_HandleTypeDef *huart) +{ + + GPIO_InitTypeDef GPIO_InitStruct; + if (huart->Instance == SFU_UART) + { + /* Peripheral Clock Enable */ + SFU_UART_CLK_ENABLE(); + + /* GPIO Ports Clock Enable */ + SFU_UART_TX_GPIO_CLK_ENABLE(); + SFU_UART_RX_GPIO_CLK_ENABLE(); + + /*Configure GPIO pins : SFU_UART_TX_Pin */ + GPIO_InitStruct.Pin = SFU_UART_TX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = SFU_UART_TX_AF; + HAL_GPIO_Init(SFU_UART_TX_GPIO_PORT, &GPIO_InitStruct); + + /*Configure GPIO pins : SFU_UART_RX_Pin */ + GPIO_InitStruct.Pin = SFU_UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = SFU_UART_RX_AF; + HAL_GPIO_Init(SFU_UART_RX_GPIO_PORT, &GPIO_InitStruct); + + } + +} + +/** + * @brief UART MSP De-Initialization + * This function frees the hardware resources used in SFU application: + * - Disable the Peripheral's clock + * @param huart: UART handle pointer + * @retval None + */ +void SFU_LL_UART_MspDeInit(UART_HandleTypeDef *huart) +{ + + if (huart->Instance == SFU_UART) + { + /* Peripheral clock disable */ + SFU_UART_CLK_DISABLE(); + + /* GPIO DeInit*/ + HAL_GPIO_DeInit(SFU_UART_TX_GPIO_PORT, SFU_UART_TX_PIN); + HAL_GPIO_DeInit(SFU_UART_RX_GPIO_PORT, SFU_UART_RX_PIN); + + } + + +} + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +static void SFU_LL_Error_Handler(void) +{ + /* + * ADD SRC CODE HERE + */ + + while (1 == 1) + { + NVIC_SystemReset(); + } +} + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level.h new file mode 100644 index 00000000..3532844d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * @file sfu_low_level.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update low level + * interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_H +#define SFU_LOW_LEVEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief SFU CRC Configuration definition + */ +typedef enum +{ + SFU_CRC_CONFIG_NONE = 0U, /*!< None */ + SFU_CRC_CONFIG_DEFAULT, /*!< Default configuration */ + SFU_CRC_CONFIG_16BIT /*!< 16 bit configuration */ +} SFU_CRC_ConfigTypeDef; + +/* Exported constants --------------------------------------------------------*/ +#define SFU_UART USART2 +#define SFU_UART_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() +#define SFU_UART_CLK_DISABLE() __HAL_RCC_USART2_CLK_DISABLE() + +#define SFU_UART_TX_AF GPIO_AF7_USART2 +#define SFU_UART_TX_GPIO_PORT GPIOA +#define SFU_UART_TX_PIN GPIO_PIN_2 +#define SFU_UART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_UART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() + +#define SFU_UART_RX_AF GPIO_AF7_USART2 +#define SFU_UART_RX_GPIO_PORT GPIOA +#define SFU_UART_RX_PIN GPIO_PIN_3 +#define SFU_UART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_UART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() + +/* Uncomment to enable the adequate Clock Source */ +#define RTC_CLOCK_SOURCE_LSI +/*#define RTC_CLOCK_SOURCE_LSE*/ + +#ifdef RTC_CLOCK_SOURCE_LSI +#define RTC_ASYNCH_PREDIV 0x1FU +#define RTC_SYNCH_PREDIV 0x3FF +#endif /* RTC_CLOCK_SOURCE_LSI */ + +#ifdef RTC_CLOCK_SOURCE_LSE +#define RTC_ASYNCH_PREDIV 0x7FU +#define RTC_SYNCH_PREDIV 0x00FFU +#endif /* RTC_CLOCK_SOURCE_LSE */ + +/* External variables --------------------------------------------------------*/ +extern __IO uint32_t DummyMemAccess; +#if defined(SFU_LOW_LEVEL_C) +#if defined(IT_MANAGEMENT) + +/* Dummy memory access : avoid compilation issue with STM32_Secure_Engine middleware + but not meaningful for this product */ +__IO uint32_t DummyMemAccess; +#endif /* defined(IT_MANAGEMENT) */ +#endif /* defined(SFU_LOW_LEVEL_C) */ + + +/* Exported macros -----------------------------------------------------------*/ +#define IS_SFU_CRC_CONF(CONF) (((CONF) == SFU_CRC_CONFIG_NONE) || \ + ((CONF) == SFU_CRC_CONFIG_DEFAULT) || \ + ((CONF) == SFU_CRC_CONFIG_16BIT)) + +/* Dummy memory access : avoid compilation issue with STM32_Secure_Engine middleware + but not meaningful for this product */ +#define SFU_LL_DummyAccess() \ + do{ \ + }while(0) + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_Init(void); +SFU_ErrorStatus SFU_LL_DeInit(void); + +SFU_ErrorStatus SFU_LL_CRC_Init(void); +SFU_ErrorStatus SFU_LL_CRC_Config(SFU_CRC_ConfigTypeDef eCRCConfg); +uint32_t SFU_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t BufferLength); + +SFU_ErrorStatus SFU_LL_UART_Init(void); +SFU_ErrorStatus SFU_LL_UART_DeInit(void); +SFU_ErrorStatus SFU_LL_UART_Transmit(uint8_t *pData, uint16_t DataLength, uint32_t Timeout); +SFU_ErrorStatus SFU_LL_UART_Receive(uint8_t *pData, uint16_t DataLength, uint32_t Timeout); +SFU_ErrorStatus SFU_LL_UART_Flush(void); + +#ifndef SFU_TAMPER_PROTECT_ENABLE +SFU_ErrorStatus SFU_LL_RTC_Init(void); +SFU_ErrorStatus SFU_LL_RTC_DeInit(void); +#endif /*SFU_TAMPER_PROTECT_ENABLE*/ + +void SFU_LL_RTC_MspInit(RTC_HandleTypeDef *hrtc); +void SFU_LL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc); +void SFU_LL_UART_MspInit(UART_HandleTypeDef *huart); +void SFU_LL_UART_MspDeInit(UART_HandleTypeDef *huart); + + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash.c new file mode 100644 index 00000000..4cea3348 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash.c @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash.c + * @author MCD Application Team + * @brief SFU Flash Low Level Interface module + * This file provides set of firmware functions to manage SFU flash + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_flash_ext.h" +#include "sfu_fwimg_regions.h" + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Initialize internal and external flash interface (OSPI/QSPI) + * @param none + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + + e_ret_status = SFU_LL_FLASH_INT_Init(); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_EXT_Init(); + } + return e_ret_status; +} + +/** + * @brief Depending on start address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pFlashStatus: SFU_FLASH Status pointer + * @param pStart: flash address to be erased + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) +{ + + /* Check Flash start address */ + if ((uint32_t) pStart < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Erase_Size(pFlashStatus, pStart, Length); + } + else + { + return SFU_LL_FLASH_EXT_Erase_Size(pFlashStatus, pStart, Length); + } +} + +/** + * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pFlashStatus: FLASH_StatusTypeDef + * @param pDestination: flash address to write + * @param pSource: pointer on buffer with data to write + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length) +{ + /* Check Flash destination address */ + if ((uint32_t) pDestination < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Write(pFlashStatus, pDestination, pSource, Length); + } + else + { + return SFU_LL_FLASH_EXT_Write(pFlashStatus, pDestination, pSource, Length); + } +} + +/** + * @brief Depending on source address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pDestination: pointer on buffer to store data + * @param pSource: flash address to read + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + /* Check Flash source address */ + if ((uint32_t) pSource < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Read(pDestination, pSource, Length); + } + else + { + return SFU_LL_FLASH_EXT_Read(pDestination, pSource, Length); + } +} + +/** + * @brief This function compare a buffer with a flash area + * @note The flash area should not be located inside the secure area + * @param pFlash: address of the flash area + * @param Pattern1: first 32 bits pattern to be compared + * @param Pattern2: second 32 bits pattern to be compared + * @param Length: number of bytes to be compared + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length) +{ + /* Check Flash source address */ + if ((uint32_t) pFlash < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Compare(pFlash, Pattern1, Pattern2, Length); + } + else + { + return SFU_LL_FLASH_EXT_Compare(pFlash, Pattern1, Pattern2, Length); + } +} + +/** + * @brief This function configure the flash to be able to execute code + * @param Addr: flash address + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Config_Exe(uint32_t SlotNumber) +{ + /* + * Internal flash : nothing to do + * External flash : configure memory mapped mode + */ + + /* Check Flash address */ + if (SlotStartAdd[SlotNumber] < EXTERNAL_FLASH_ADDRESS) + { + return SFU_SUCCESS; + } + else + { + return SFU_LL_FLASH_EXT_Config_Exe(SlotNumber); + } +} + +/** + * @brief Gets the page of a given address + * @param Addr: flash address + * @retval The page of a given address + */ +uint32_t SFU_LL_FLASH_GetPage(uint32_t Addr) +{ + /* Check Flash address */ + if (Addr < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_GetPage(Addr); + } + else + { + return INVALID_PAGE; /* Page number is not used in SBSFU application for external flash */ + } +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash.h new file mode 100644 index 00000000..726365d6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update flash + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_FLASH_H +#define SFU_LOW_LEVEL_FLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + SFU_FLASH_ERROR = 0U, /*!< Error Flash generic*/ + SFU_FLASH_ERR_HAL, /*!< Error Flash HAL init */ + SFU_FLASH_ERR_ERASE, /*!< Error Flash erase */ + SFU_FLASH_ERR_WRITING, /*!< Error writing data in Flash */ + SFU_FLASH_ERR_WRITINGCTRL, /*!< Error checking data written in Flash */ + SFU_FLASH_SUCCESS /*!< Flash Success */ +} SFU_FLASH_StatusTypeDef; + +/* Exported constants --------------------------------------------------------*/ +#define INVALID_SECTOR 0xFFFFFFFFU +#define INVALID_PAGE 0xFFFFFFFFU +#define INVALID_BANK 0xFFFFFFFFU + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_FLASH_Init(void); +SFU_ErrorStatus SFU_LL_FLASH_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Config_Exe(uint32_t SlotNumber); + +uint32_t SFU_LL_FLASH_GetPage(uint32_t Addr); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_FLASH_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c new file mode 100644 index 00000000..7b10b14d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c @@ -0,0 +1,80 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_ext.c + * @author MCD Application Team + * @brief SFU Flash Low Level Interface module + * This file provides set of firmware functions to manage SFU external + * flash low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level_flash_ext.h" +#include "sfu_low_level_security.h" + +/* Private defines -----------------------------------------------------------*/ + +/* Functions Definition ------------------------------------------------------*/ + +/* No external flash available on this product + ==> return SFU_ERROR except for SFU_LL_FLASH_EXT_Init and SFU_LL_FLASH_EXT_Config_Exe which are called + systematically during startup phase */ + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Init(void) +{ + return SFU_SUCCESS; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) +{ + UNUSED(pFlashStatus); + UNUSED(pStart); + UNUSED(Length); + return SFU_ERROR; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length) +{ + UNUSED(pFlashStatus); + UNUSED(pDestination); + UNUSED(pSource); + UNUSED(Length); + return SFU_ERROR; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + UNUSED(pDestination); + UNUSED(pSource); + UNUSED(Length); + return SFU_ERROR; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length) +{ + UNUSED(pFlash); + UNUSED(Pattern1); + UNUSED(Pattern2); + UNUSED(Length); + return SFU_ERROR; +} +SFU_ErrorStatus SFU_LL_FLASH_EXT_Config_Exe(uint32_t SlotNumber) +{ + UNUSED(SlotNumber); + return SFU_SUCCESS; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h new file mode 100644 index 00000000..08566d80 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_ext.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update low level + * interface for external flash. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_FLASH_EXT_H +#define SFU_LOW_LEVEL_FLASH_EXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_low_level_flash.h" +#include "main.h" +#include "sfu_def.h" + +/* Exported constants --------------------------------------------------------*/ +#define EXTERNAL_FLASH_ADDRESS 0x90000000U + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_FLASH_EXT_Init(void); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Config_Exe(uint32_t SlotNumber); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_FLASH_EXT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c new file mode 100644 index 00000000..1e8db303 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c @@ -0,0 +1,474 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_int.c + * @author MCD Application Team + * @brief SFU Flash Low Level Interface module + * This file provides set of firmware functions to manage SFU internal + * flash low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "se_interface_bootloader.h" +#include "string.h" +#include "sfu_fsm_states.h" +#include "sfu_error.h" + +/* Private defines -----------------------------------------------------------*/ +#define NB_PAGE_SECTOR_PER_ERASE 2U /*!< Nb page erased per erase */ + +/* Private variables ---------------------------------------------------------*/ +static __IO uint32_t DoubleECC_Error_Counter = 0U; + + +static SFU_ErrorStatus SFU_LL_FLASH_INT_Clear_Error(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief This function initialize the internal flash interface if required + * @param none + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Init(void) +{ + return SFU_SUCCESS; +} + +/** + * @brief This function does an erase of n (depends on Length) pages in user flash area + * @param pFlashStatus: SFU_FLASH Status pointer + * @param pStart: flash address to be erased + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) +{ + uint32_t page_error = 0U; + uint32_t start = (uint32_t)pStart; + FLASH_EraseInitTypeDef p_erase_init; + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t first_page; + uint32_t nb_pages; + uint32_t chunk_nb_pages; + uint32_t length = Length; + + /* Check the pointers allocation */ + if (pFlashStatus == NULL) + { + return SFU_ERROR; + } + + *pFlashStatus = SFU_FLASH_SUCCESS; + + /* Clear error flags raised during previous operation */ + e_ret_status = SFU_LL_FLASH_INT_Clear_Error(); + + if (e_ret_status == SFU_SUCCESS) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + first_page = SFU_LL_FLASH_INT_GetPage(start); + /* Get the number of pages to erase from 1st page */ + nb_pages = SFU_LL_FLASH_INT_GetPage(start + length - 1U) - first_page + 1U; + p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + /* Erase flash per NB_PAGE_SECTOR_PER_ERASE to avoid watch-dog */ + do + { + chunk_nb_pages = (nb_pages >= NB_PAGE_SECTOR_PER_ERASE) ? NB_PAGE_SECTOR_PER_ERASE : nb_pages; + p_erase_init.Page = first_page; + p_erase_init.NbPages = chunk_nb_pages; + first_page += chunk_nb_pages; + nb_pages -= chunk_nb_pages; + if (HAL_FLASHEx_Erase(&p_erase_init, &page_error) != HAL_OK) + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERR_ERASE; + } + SFU_LL_SECU_IWDG_Refresh(); /* calling this function which checks the compiler switch */ + } while (nb_pages > 0U); + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + if (HAL_FLASH_Lock() != HAL_OK) + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERR_HAL; + } + } + else + { + *pFlashStatus = SFU_FLASH_ERR_HAL; + } + } + + return e_ret_status; +} + +/** + * @brief This function writes a data buffer in flash (data are 32-bit aligned). + * @note After writing data buffer, the flash content is checked. + * @param pFlashStatus: FLASH_StatusTypeDef + * @param pDestination: Start address for target location. It has to be 8 bytes aligned. + * @param pSource: pointer on buffer with data to write + * @param Length: Length of data buffer in bytes. It has to be 8 bytes aligned. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t i; + uint32_t inside_header = 0U; + uint32_t destination = (uint32_t)pDestination; + uint32_t source = (uint32_t)pSource; + + /* Check the pointers allocation */ + if ((pFlashStatus == NULL) || (pSource == NULL)) + { + return SFU_ERROR; + } + + /* Is destination area inside 1 of the firmware image headers ? */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((destination >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((destination + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + inside_header = 1U; + } + } + + /* Destination area part of 1 of the firmware image headers : + writing operation should be executed inside secure environment */ + if ((inside_header == 1U) && (Length != 0U)) + { + /* SE Access */ + SE_StatusTypeDef se_status; + SE_ErrorStatus se_ret_status = SE_SFU_IMG_Write(&se_status, (uint8_t *)destination, pSource, Length); + if (se_ret_status == SE_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + *pFlashStatus = SFU_FLASH_SUCCESS; + } + else + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERROR; + } + } + /* Writing operation executed by SBSFU */ + else + { + *pFlashStatus = SFU_FLASH_ERROR; + + /* Clear error flags raised during previous operation */ + e_ret_status = SFU_LL_FLASH_INT_Clear_Error(); + + if (e_ret_status == SFU_SUCCESS) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() != HAL_OK) + { + *pFlashStatus = SFU_FLASH_ERR_HAL; + + } + else + { + /* DataLength must be a multiple of 64 bit */ + for (i = 0U; (i < Length) && (e_ret_status == SFU_SUCCESS); i += sizeof(SFU_LL_FLASH_write_t)) + { + *pFlashStatus = SFU_FLASH_ERROR; + + /* Device voltage range supposed to be [2.7V to 3.6V], the operation will + be done by word */ + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, destination, *((uint64_t *)(source + i))) + == HAL_OK) + { + /* Check the written value */ + if (*(uint64_t *)destination != *(uint64_t *)(source + i)) + { + /* Flash content doesn't match SRAM content */ + *pFlashStatus = SFU_FLASH_ERR_WRITINGCTRL; + e_ret_status = SFU_ERROR; + } + else + { + /* Increment FLASH Destination address */ + destination = destination + sizeof(SFU_LL_FLASH_write_t); + e_ret_status = SFU_SUCCESS; + *pFlashStatus = SFU_FLASH_SUCCESS; + } + } + else + { + /* Error occurred while writing data in Flash memory */ + *pFlashStatus = SFU_FLASH_ERR_WRITING; + e_ret_status = SFU_ERROR; + } + } + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) */ + if (HAL_FLASH_Lock() != HAL_OK) + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERR_HAL; + } + } + } + } + return e_ret_status; +} + +/** + * @brief This function reads flash + * @param pDestination: Start address for target location + * @param pSource: flash address to read + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_ErrorStatus se_ret_status; + SE_StatusTypeDef se_status; + uint32_t i; + uint32_t inside_header = 0U; + uint32_t source = (uint32_t)pSource; + + /* Is destination area inside 1 of the firmware image headers ? */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((source >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((source + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + inside_header = 1U; + } + } + + /* Destination area part of 1 of the firmware image headers : + reading operation should be executed inside secure environment */ + if (inside_header == 1U) + { + /* SE Access */ + DoubleECC_Error_Counter = 0U; + se_ret_status = SE_SFU_IMG_Read(&se_status, pDestination, (uint8_t *)source, Length); + if ((se_ret_status == SE_SUCCESS) && (DoubleECC_Error_Counter == 0U)) + { + e_ret_status = SFU_SUCCESS; + } + DoubleECC_Error_Counter = 0U; + } + /* Reading operation executed by SBSFU */ + else + { + DoubleECC_Error_Counter = 0U; + /* Do not use memcpy from lib : ECC error should be checked at each loop */ + for (i = 0; (i < Length) && (DoubleECC_Error_Counter == 0U); i++, pDestination++, pSource++) + { + *pDestination = *pSource; + } + if (DoubleECC_Error_Counter == 0U) + { + e_ret_status = SFU_SUCCESS; + } + DoubleECC_Error_Counter = 0U; + } + return e_ret_status; +} + +/** + * @brief This function compare a buffer with a flash area + * @note The flash area should not be located inside the secure area + * @param pFlash: address of the flash area + * @param Pattern1: first 32 bits pattern to be compared + * @param Pattern2: second 32 bits pattern to be compared + * @param Length: number of bytes to be compared + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length) +{ + uint32_t flash = (uint32_t) pFlash; + uint32_t i; + + /* Comparison executed by SBSFU ==> flash area could not be located inside secured environment */ + for ( i = 0U; i < Length; i += 4U) + { + if ((*(uint32_t *)(flash + i) != Pattern1) && (*(uint32_t *)(flash + i) != Pattern2)) + { + return SFU_ERROR; + } + } + return SFU_SUCCESS; +} + +/** + * @brief Gets the page of a given address + * @param Addr: flash address + * @retval The page of a given address + */ +uint32_t SFU_LL_FLASH_INT_GetPage(uint32_t Addr) +{ + uint32_t page; + + page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE; + + return page; +} + + + + +/** + * @brief Clear error flags raised during previous operation + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_LL_FLASH_INT_Clear_Error(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Unlock the Program memory */ + if (HAL_FLASH_Unlock() == HAL_OK) + { + + /* Clear all FLASH flags */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); + + /* Unlock the Program memory */ + if (HAL_FLASH_Lock() == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + } + + return e_ret_status; + +} + + +/** + * @brief Get Link Register value (LR) + * @param None. + * @retval LR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_LR(void) +{ + register uint32_t result; + +#if defined ( __ICCARM__ ) || ( __GNUC__ ) + __ASM volatile("MOV %0, LR" : "=r"(result)); +#elif defined ( __CC_ARM ) + __ASM volatile("MOV result, __return_address()"); +#endif /* ( __ICCARM__ ) || ( __GNUC__ ) */ + + return result; +} + +/* + As this handler code relies on stack pointer position to manipulate the PC return value, it is important + not to use extra registers (on top of scratch registers), because it would change the stack pointer + position. Then compiler optimizations are customized to ensure that. +*/ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O1"))) +#endif /* __ICCARM__ */ +/** + * @brief NMI Handler present for handling Double ECC NMI interrupt + * @param None. + * @retvat void + */ +void NMI_Handler(void) +{ + uint32_t *p_sp; + uint32_t lr; + uint16_t opcode_msb; + + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)) + { + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); + + /* Memorize error to ignore the read value */ + DoubleECC_Error_Counter++; + + lr = __get_LR(); + + /* Check EXC_RETURN value in LR to know which SP was used prior entering exception */ + if (((lr) & (0xFU)) == 0xDU) + { + /* interrupted code was using Process Stack Pointer */ + p_sp = (uint32_t *)__get_PSP(); + } + else + { + /* interrupted code was using Main Stack Pointer */ + p_sp = (uint32_t *)__get_MSP(); + } + + /* Test caller mode T bit from CPSR in stack */ + if ((*(p_sp + 7U) & (1U << xPSR_T_Pos)) != 0U) + { + /* Thumb mode. + Test PC in stack. + If bits [15:11] of the halfword being decoded take any of the following values, + the halfword is the first halfword of a 32-bit instruction: 0b11101, 0b11110, 0b11111. + Otherwise, the halfword is a 16-bit instruction. + */ + opcode_msb = (*(uint16_t *)(*(p_sp + 6) & 0xFFFFFFFEU) & 0xF800U); + if ((opcode_msb == 0xE800U) || (opcode_msb == 0xF000U) || (opcode_msb == 0xF800U)) + { + /* execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + else + { + /* execute next instruction PC +2 */ + *(p_sp + 6U) += 2U; + } + } + else + { + /* ARM mode execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + } + else + { + while (1 == 1) + { + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_UNKNOWN); + } + } +} + + +/** + * @brief HardFault Handler + * @param None. + * @retval None. + */ +void HardFault_Handler(void) +{ + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_HARD_FAULT); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h new file mode 100644 index 00000000..5ef51fc6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_int.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update low level + * interface for internal flash. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_FLASH_INT_H +#define SFU_LOW_LEVEL_FLASH_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_low_level_flash.h" +#include "main.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief Flash Write Access Constraints (size and alignment) + * + * For instance, on L4, it is only possible to program double word (2 x 32-bit data). + * See http://www.st.com/content/ccc/resource/technical/document/reference_manual/02/35/09/0c/4f/f7/40/03/DM00083560.pdf/files/DM00083560.pdf/jcr:content/translations/en.DM00083560.pdf + * + * @note This type is very important for the FWIMG module (see @ref SFU_IMG). + * \li This is the type to be used for an atomic write in FLASH: see @ref AtomicWrite. + * \li The size of this type changes the size of the TRAILER area at the end of dwl slot, + * as it is used to tag if a Firmware Image chunk has been swapped or not (see @ref SFU_IMG_FirmwareToResume). + */ + +/* double-word is the default setting for most platforms */ +typedef uint64_t SFU_LL_FLASH_write_t; + +/* Exported constants --------------------------------------------------------*/ +/** + * Length of a MAGIC tag (32 bytes). + * This must be a multiple of @ref SFU_LL_FLASH_write_t with a minimum value of 32. + */ +#define MAGIC_LENGTH ((uint32_t)32U) + +/* External variables --------------------------------------------------------*/ +#define IS_ALIGNED(address) (0U == ((address) % FLASH_PAGE_SIZE)) + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Init(void); +SFU_ErrorStatus SFU_LL_FLASH_INT_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_INT_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_INT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_INT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length); +uint32_t SFU_LL_FLASH_INT_GetPage(uint32_t Addr); +void NMI_Handler(void); +void HardFault_Handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_FLASH_INT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_security.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_security.c new file mode 100644 index 00000000..de1341a5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_security.c @@ -0,0 +1,1104 @@ +/** + ****************************************************************************** + * @file sfu_low_level_security.c + * @author MCD Application Team + * @brief SFU Security Low Level Interface module + * This file provides set of firmware functions to manage SFU security + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level_security.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level.h" +#include "sfu_trace.h" +#include "sfu_boot.h" +#include "sfu_fsm_states.h" /* needed for sfu_error.h */ +#include "sfu_error.h" +#include "stm32wlxx_it.h" + +#ifndef SFU_WRP_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_WRP_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_WRP_PROTECT_ENABLE */ + +#ifndef SFU_RDP_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_RDP_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_RDP_PROTECT_ENABLE */ + + +#ifndef SFU_MPU_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_MPU_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_MPU_PROTECT_ENABLE */ + + + +#ifndef SFU_TAMPER_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_TAMPER_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + +#ifndef SFU_DAP_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_DAP_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_DAP_PROTECT_ENABLE */ + +#ifndef SFU_DMA_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_DMA_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_DMA_PROTECT_ENABLE */ + +#ifndef SFU_IWDG_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_IWDG_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_IWDG_PROTECT_ENABLE */ + + +/* Private typedef -----------------------------------------------------------*/ +typedef enum +{ + SFU_FALSE = 0U, + SFU_TRUE = !SFU_FALSE +} SFU_BoolTypeDef; + +typedef struct +{ + uint8_t Number; /*!< Specifies the number of the region to protect. This parameter can be a + value of CORTEX_MPU_Region_Number */ + uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */ + uint8_t Size; /*!< Specifies the size of the region to protect. */ + uint8_t AccessPermission; /*!< Specifies the region access permission type. This parameter can be a + value of CORTEX_MPU_Region_Permission_Attributes */ + uint8_t DisableExec; /*!< Specifies the instruction access status. This parameter can be a value + of CORTEX_MPU_Instruction_Access */ + uint8_t SubRegionDisable; /*!< Specifies the sub region field (region is divided in 8 slices) when bit + is 1 region sub region is disabled */ +} SFU_MPU_InitTypeDef; + +typedef uint32_t SFU_ProtectionTypeDef; /*!< SFU HAL IF Protection Type Def*/ + +/* Private variables ---------------------------------------------------------*/ +#ifdef SFU_IWDG_PROTECT_ENABLE +static IWDG_HandleTypeDef IwdgHandle; + +#endif /* SFU_IWDG_PROTECT_ENABLE */ +#ifdef SFU_MPU_PROTECT_ENABLE +static SFU_MPU_InitTypeDef MpuAreas[] = + + { + { + MPU_REGION_NUMBER0, SFU_PROTECT_MPU_AREA_USER_START, SFU_PROTECT_MPU_AREA_USER_SIZE, + SFU_PROTECT_MPU_AREA_USER_PERM, SFU_PROTECT_MPU_AREA_USER_EXEC, SFU_PROTECT_MPU_AREA_USER_SREG + }, +{ + MPU_REGION_NUMBER1, SFU_PROTECT_MPU_AREA_SFUEN_START_0, SFU_PROTECT_MPU_AREA_SFUEN_SIZE_0, + SFU_PROTECT_MPU_AREA_SFUEN_PERM, SFU_PROTECT_MPU_AREA_SFUEN_EXEC, SFU_PROTECT_MPU_AREA_SFUEN_SREG_0 +}, +#if !defined(__GNUC__) +{ + MPU_REGION_NUMBER2, SFU_PROTECT_MPU_AREA_SFUEN_START_1, SFU_PROTECT_MPU_AREA_SFUEN_SIZE_1, + SFU_PROTECT_MPU_AREA_SFUEN_PERM, SFU_PROTECT_MPU_AREA_SFUEN_EXEC, SFU_PROTECT_MPU_AREA_SFUEN_SREG_1 +}, +#endif /* !__GNUC__ */ +{ + MPU_REGION_NUMBER3, SFU_PROTECT_MPU_AREA_VECT_START, SFU_PROTECT_MPU_AREA_VECT_SIZE, + SFU_PROTECT_MPU_AREA_VECT_PERM, SFU_PROTECT_MPU_AREA_VECT_EXEC, SFU_PROTECT_MPU_AREA_VECT_SREG +}, +{ + MPU_REGION_NUMBER4, SFU_PROTECT_MPU_AREA_OB_BANK1_START, SFU_PROTECT_MPU_AREA_OB_BANK1_SIZE, + SFU_PROTECT_MPU_AREA_OB_BANK1_PERM, SFU_PROTECT_MPU_AREA_OB_BANK1_EXEC, SFU_PROTECT_MPU_AREA_OB_BANK1_SREG +}, +{ + MPU_REGION_NUMBER5, SFU_PROTECT_MPU_AREA_PERIPH_START, SFU_PROTECT_MPU_AREA_PERIPH_SIZE, + SFU_PROTECT_MPU_AREA_PERIPH_PERM, SFU_PROTECT_MPU_AREA_PERIPH_EXEC, SFU_PROTECT_MPU_AREA_PERIPH_SREG +}, + }; +#endif /* SFU_MPU_PROTECT_ENABLE */ + +/* Private function prototypes -----------------------------------------------*/ +static SFU_ErrorStatus SFU_LL_SECU_CheckFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes); +static SFU_ErrorStatus SFU_LL_SECU_SetFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied); + +#ifdef SFU_RDP_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionRDP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied); +#endif /*SFU_RDP_PROTECT_ENABLE*/ + +#ifdef SFU_WRP_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_CheckProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes); +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied); +#endif /*SFU_WRP_PROTECT_ENABLE*/ + + + + +#ifdef SFU_IWDG_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionIWDG(void); +#endif /*SFU_IWDG_PROTECT_ENABLE*/ + +#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionCLOCK_MONITOR(void); +#endif /*SFU_CLCK_MNTR_PROTECT_ENABLE*/ + +#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionTEMP_MONITOR(void); +#endif /*SFU_TEMP_MNTR_PROTECT_ENABLE*/ + + + +/* Functions Definition : helper ---------------------------------------------*/ +#ifdef SFU_MPU_PROTECT_ENABLE +/** + * @brief Check MPU configuration + * @param MPU_InitStruct Configuration to be checked + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus MPU_CheckConfig(MPU_Region_InitTypeDef *pMPUInitStruct) +{ + uint32_t mpu_rasr = 0UL; + + /* Set the Region number */ + MPU->RNR = pMPUInitStruct->Number; + + mpu_rasr |= (((uint32_t)pMPUInitStruct->DisableExec << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->AccessPermission << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->TypeExtField << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->IsShareable << MPU_RASR_S_Pos) & MPU_RASR_S_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->IsCacheable << MPU_RASR_C_Pos) & MPU_RASR_C_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->IsBufferable << MPU_RASR_B_Pos) & MPU_RASR_B_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->SubRegionDisable << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->Size << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->Enable << MPU_RASR_ENABLE_Pos) & MPU_RASR_ENABLE_Msk); + + if (((MPU->RBAR & MPU_RBAR_ADDR_Msk) == pMPUInitStruct->BaseAddress) && (MPU->RASR == mpu_rasr)) + { + return SFU_SUCCESS; + } + else + { + return SFU_ERROR; + } +} +#endif /* SFU_MPU_PROTECT_ENABLE */ + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Check and if not applied apply the Static security protections to + * all the SfuEn Sections in Flash: RDP, WRP, PCRoP. Static security protections + * those protections not impacted by a Reset. They are set using the Option Bytes + * When the device is locked (RDP Level2), these protections cannot be changed anymore + * @param None + * @note By default, the best security protections are applied to the different + * flash sections in order to maximize the security level for the specific MCU. + * @retval uint32_t CRC (returned value is the combination of all the applied protections. + * If different from SFU_STD_PROTECTION_ALL, 1 or more protections cannot be applied) + */ +SFU_ErrorStatus SFU_LL_SECU_CheckApplyStaticProtections(void) +{ + FLASH_OBProgramInitTypeDef flash_option_bytes; + SFU_BoolTypeDef is_protection_to_be_applied = SFU_FALSE; + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + uint32_t i_protection_set = 0U; + uint32_t i_ctrl = 0U; + + /* Unlock the Flash to enable the flash control register access *************/ + (void) HAL_FLASH_Unlock(); + + /* Clear OPTVERR bit set on virgin samples */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); + + /* Unlock the Options Bytes *************************************************/ + (void) HAL_FLASH_OB_Unlock(); + + /* Get Option Bytes status for WRP AREA_A **********/ + flash_option_bytes.WRPArea = SFU_PROTECT_WRP_AREA_1; + (void) HAL_FLASHEx_OBGetConfig(&flash_option_bytes); + + /* Check/Apply RDP_Level 1. This is the minimum protection allowed */ + /* if RDP_Level 2 is already applied it's not possible to modify the OptionBytes anymore */ + if (flash_option_bytes.RDPLevel == OB_RDP_LEVEL_2) + { + /* Sanity check of the (enabled) static protections */ + if (SFU_LL_SECU_CheckFlashConfiguration(&flash_option_bytes) != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] Flash configuration failed! Product blocked."); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } + +#ifdef SFU_WRP_PROTECT_ENABLE + if (SFU_LL_SECU_CheckProtectionWRP(&flash_option_bytes) != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] System Security Configuration failed! Product blocked."); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } +#endif /* SFU_WRP_PROTECT_ENABLE */ + + + + /*RDP level 2 ==> Flow control by-passed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); + } + else + { + /* Check/Set Flash configuration *******************************************/ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_SECU_SetFlashConfiguration(&flash_option_bytes, &is_protection_to_be_applied); + } + i_ctrl++; + + /* Check/Apply WRP ********************************************************/ +#ifdef SFU_WRP_PROTECT_ENABLE + if (e_ret_status == SFU_SUCCESS) + { + i_protection_set++; + e_ret_status = SFU_LL_SECU_SetProtectionWRP(&flash_option_bytes, &is_protection_to_be_applied); + } + i_ctrl++; +#endif /* SFU_WRP_PROTECT_ENABLE */ + + /* Check/Apply PCRoP ******************************************************/ + + + /* Check/Apply RDP : RDP-L2 should be done as last option bytes configuration */ +#ifdef SFU_RDP_PROTECT_ENABLE + if (e_ret_status == SFU_SUCCESS) + { + i_protection_set++; + e_ret_status = SFU_LL_SECU_SetProtectionRDP(&flash_option_bytes, &is_protection_to_be_applied); + } + i_ctrl++; +#endif /* SFU_RDP_PROTECT_ENABLE */ + + if (e_ret_status == SFU_SUCCESS) + { + i_protection_set++; + if (is_protection_to_be_applied) + { + /* Generate System Reset to reload the new option byte values *************/ + /* WARNING: This means that if a protection can't be set, there will be a reset loop! */ + (void) HAL_FLASH_OB_Launch(); + } + } + } + + if (i_protection_set != i_ctrl) + { + e_ret_status = SFU_ERROR; + } + + /* Lock the Options Bytes ***************************************************/ + (void) HAL_FLASH_OB_Lock(); + + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + (void) HAL_FLASH_Lock(); + + /* If it was not possible to apply one of the above mandatory protections, the + Option bytes have not been reloaded. Return the error status in order for the + caller function to take the right actions */ + return e_ret_status; + +} + +/** + * @brief Apply Runtime security protections. + * Runtime security protections have to be re-configured at each Reset. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_CheckApplyRuntimeProtections(uint8_t uStep) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + SFU_ProtectionTypeDef runtime_protection = SFU_PROTECTIONS_NONE; + uint32_t i_protection_set = 0U; + uint32_t i_ctrl = 0U; + + /* Depending on compilation switches, prevent compilation warning */ + UNUSED(runtime_protection); + + +#ifdef SFU_MPU_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionMPU(uStep) == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_MPU; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_MPU_PROTECT_ENABLE */ + + + + /* Check/Apply disable DMAs ************************************************/ +#ifdef SFU_DMA_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionDMA() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_DMA; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_DMA_PROTECT_ENABLE */ + + /* Check/Apply IWDG **************************************************/ +#ifdef SFU_IWDG_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionIWDG() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_IWDG; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_IWDG_PROTECT_ENABLE */ + + /* Check/Apply DAP *********************************************************/ +#ifdef SFU_DAP_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionDAP() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_DAP; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#else +#endif /* SFU_DAP_PROTECT_ENABLE */ + + /* Check/Apply ANTI_TAMPER *************************************************/ +#ifdef SFU_TAMPER_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionANTI_TAMPER() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_ANTI_TAMPER; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#else +#ifdef SFU_TEST_PROTECTION + if (SFU_LL_RTC_Init() != SFU_SUCCESS) + { + e_ret_status = SFU_ERROR; + } +#endif /* SFU_TEST_PROTECTION */ +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + /* Check/Apply CLOCK_MONITOR **********************************************/ +#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionCLOCK_MONITOR() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_CLOCK_MONITOR; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_CLCK_MNTR_PROTECT_ENABLE */ + + /* Check/Apply TEMP_MONITOR **********************************************/ +#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionTEMP_MONITOR() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_TEMP_MONITOR; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_TEMP_MNTR_PROTECT_ENABLE */ + +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n= [SBOOT] RuntimeProtections: %x", runtime_protection); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + if (i_protection_set != i_ctrl) + { + e_ret_status = SFU_ERROR; + } + + return e_ret_status; +} + +/** + * @brief Return the reset source detected after a reboot. The related flag is reset + * at the end of this function. + * @param peResetpSourceId: to be filled with the detected source of reset + * @note In case of multiple reset sources this function return only one of them. + * It can be improved returning and managing a combination of them. + * @retval SFU_SUCCESS if successful, SFU_ERROR otherwise + */ +void SFU_LL_SECU_GetResetSources(SFU_RESET_IdTypeDef *peResetpSourceId) +{ + /* Check if the last reset has been generated from a Watchdog exception */ + if ((__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) || + (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)) + { + *peResetpSourceId = SFU_RESET_WDG_RESET; + + } + + + /* Check if the last reset has been generated from a Low Power reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) != RESET) + { + *peResetpSourceId = SFU_RESET_LOW_POWER; + + } + + /* Check if the last reset has been generated from a Software reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) != RESET) + { + *peResetpSourceId = SFU_RESET_SW_RESET; + + } + /* Check if the last reset has been generated from an Option Byte Loader reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST) != RESET) + { + *peResetpSourceId = SFU_RESET_OB_LOADER; + } + /* Check if the last reset has been generated from a Hw pin reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET) + { + *peResetpSourceId = SFU_RESET_HW_RESET; + + } + /* Unknown */ + else + { + *peResetpSourceId = SFU_RESET_UNKNOWN; + } +} + +/** + * @brief Clear the reset sources. This function should be called after the actions + * on the reset sources has been already taken. + * @param none + * @note none + * @retval none + */ +void SFU_LL_SECU_ClearResetSources() +{ + /* Clear reset flags */ + __HAL_RCC_CLEAR_RESET_FLAGS(); +} + +/** + * @brief Refresh Watchdog : reload counter + * This function must be called just before jumping to the UserFirmware + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_IWDG_Refresh(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + +#ifdef SFU_IWDG_PROTECT_ENABLE + /* Refresh IWDG: reload counter */ + if (HAL_IWDG_Refresh(&IwdgHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } +#else + e_ret_status = SFU_SUCCESS; +#endif /*SFU_IWDG_PROTECT_ENABLE*/ + + return e_ret_status; +} + +/** + * @brief Check Flash configuration. + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @retval SFU_ErrorStatus SFU_SUCCESS if Flash configuration is correct, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_CheckFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check/Apply BOOT_LOCK ****************************************************/ + if ((psFlashOptionBytes->UserConfig & FLASH_OPTR_BOOT_LOCK) == OB_BOOT_LOCK_ENABLE) + { + e_ret_status = SFU_SUCCESS; + } + if (e_ret_status == SFU_SUCCESS) + { + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_UBE, FLOW_CTRL_UBE); + } + return e_ret_status; + +} + +/** + * @brief Set Flash configuration. + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if + * this OptByte has to be modified and immediately reloaded. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check Flash configuration */ + if (SFU_LL_SECU_CheckFlashConfiguration(psFlashOptionBytes) == SFU_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + } + else + { +#if defined(SECBOOT_OB_DEV_MODE) + psFlashOptionBytes->OptionType = OPTIONBYTE_USER; + psFlashOptionBytes->UserConfig &= ~OB_BOOT_LOCK_ENABLE; + psFlashOptionBytes->UserConfig |= OB_BOOT_LOCK_ENABLE; + if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) + { + *pbIsProtectionToBeApplied |= 1U; + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_UBE, FLOW_CTRL_UBE); + } +#else + TRACE("\r\n= [SBOOT] Boot Configuration issue: booting Main flash through PA14-BOOT0 pin functionality cannot be guaranteed"); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); +#endif /* SECBOOT_OB_DEV_MODE */ + } + + return e_ret_status; +} + +#ifdef SFU_RDP_PROTECT_ENABLE +/** + * @brief Apply the RDP protection + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if + * this OptByte has to be modified and immediately reloaded. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionRDP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check/Apply RDP **********************************************************/ + /* Please consider that the suggested and most secure approach is to set the RDP_LEVEL_2 */ + if (psFlashOptionBytes->RDPLevel == SFU_PROTECT_RDP_LEVEL) + { + e_ret_status = SFU_SUCCESS; /*Protection already applied */ + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); + } + else + { +#if defined(SECBOOT_OB_DEV_MODE) +#if defined(SFU_FINAL_SECURE_LOCK_ENABLE) + TRACE("\r\n\t Applying RDP-2 Level. Product locked! You might need to unplug/plug the USB cable!"); +#else + TRACE("\r\n\t Applying RDP-1 Level. You might need to unplug/plug the USB cable!"); +#endif /* SFU_FINAL_SECURE_LOCK_ENABLE */ + psFlashOptionBytes->OptionType = OPTIONBYTE_RDP; + psFlashOptionBytes->RDPLevel = SFU_PROTECT_RDP_LEVEL; + if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) + { + *pbIsProtectionToBeApplied |= 1U; + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); + } +#else + TRACE("\r\n= [SBOOT] System Security Configuration failed: RDP is incorrect. STOP!"); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); +#endif /* SECBOOT_OB_DEV_MODE */ + } + return e_ret_status; +} +#endif /*SFU_RDP_PROTECT_ENABLE*/ + +#ifdef SFU_WRP_PROTECT_ENABLE +/** + * @brief Check the WRP protection to the specified Area. It includes the SFU Vector Table + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_CheckProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check WRP ****************************************************************/ + if ((psFlashOptionBytes->WRPStartOffset == SFU_PROTECT_WRP_PAGE_START_1) && + (psFlashOptionBytes->WRPEndOffset == SFU_PROTECT_WRP_PAGE_END_1)) + { + e_ret_status = SFU_SUCCESS; /*Protection applied */ + } + if (e_ret_status == SFU_SUCCESS) + { + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_WRP, FLOW_CTRL_WRP); + } + return e_ret_status; +} + +/** + * @brief Apply the WRP protection to the specified Area. It includes the SFU Vector Table + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if + * this OptByte has to be modified and immediately reloaded. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check/Apply WRP **********************************************************/ + if (SFU_LL_SECU_CheckProtectionWRP(psFlashOptionBytes) == SFU_SUCCESS) + { + e_ret_status = SFU_SUCCESS; /*Protection already applied */ + } + else + { +#if defined(SECBOOT_OB_DEV_MODE) + psFlashOptionBytes->OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes->WRPArea = SFU_PROTECT_WRP_AREA_1; + psFlashOptionBytes->WRPStartOffset = SFU_PROTECT_WRP_PAGE_START_1; + psFlashOptionBytes->WRPEndOffset = SFU_PROTECT_WRP_PAGE_END_1; + + if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) + { + *pbIsProtectionToBeApplied |= 1U; + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_WRP, FLOW_CTRL_WRP); + } +#else + TRACE("\r\n= [SBOOT] System Security Configuration failed: WRP is incorrect. STOP!"); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); +#endif /* SECBOOT_OB_DEV_MODE */ + } + + return e_ret_status; +} +#endif /*SFU_WRP_PROTECT_ENABLE*/ + +#ifdef SFU_MPU_PROTECT_ENABLE +/** + * @brief Apply MPU protection before executing UserApp + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU_UserApp(void) +{ + MPU_Region_InitTypeDef MPU_InitStruct; + + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER6; + MPU_InitStruct.BaseAddress = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_START; + MPU_InitStruct.Size = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SIZE; + MPU_InitStruct.SubRegionDisable = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SREG; + MPU_InitStruct.AccessPermission = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_PERM; + MPU_InitStruct.DisableExec = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_EXEC; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER7; + MPU_InitStruct.BaseAddress = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_START; + MPU_InitStruct.Size = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SIZE; + MPU_InitStruct.SubRegionDisable = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SREG; + MPU_InitStruct.AccessPermission = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_PERM; + MPU_InitStruct.DisableExec = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_EXEC; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + + return SFU_SUCCESS; +} +#endif /* SFU_MPU_PROTECT_ENABLE */ + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * @brief Apply MPU protection before executing Standalone loader + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU_StandaloneLoader(void) +{ + MPU_Region_InitTypeDef MPU_InitStruct; + + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER6; + MPU_InitStruct.BaseAddress = LOADER_PROTECT_MPU_AREA_START; + MPU_InitStruct.Size = LOADER_PROTECT_MPU_AREA_SIZE; + MPU_InitStruct.SubRegionDisable = LOADER_PROTECT_MPU_AREA_SREG; + MPU_InitStruct.AccessPermission = LOADER_PROTECT_MPU_AREA_PERM; + MPU_InitStruct.DisableExec = LOADER_PROTECT_MPU_AREA_EXEC; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + return SFU_SUCCESS; +} +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + +#ifdef SFU_MPU_PROTECT_ENABLE + +/** + * @brief Apply MPU protection + * @param uStep Configuration step : SFU_INITIAL_CONFIGURATION, SFU_SECOND_CONFIGURATION, SFU_THIRD_CONFIGURATION + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU(uint8_t uStep) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t mpu_region_num; /* id of the MPU region being configured */ + MPU_Region_InitTypeDef MPU_InitStruct; + + + for (mpu_region_num = 0U; mpu_region_num < (sizeof(MpuAreas) / sizeof(SFU_MPU_InitTypeDef)); mpu_region_num++) + { + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MpuAreas[mpu_region_num].Number; + MPU_InitStruct.BaseAddress = MpuAreas[mpu_region_num].BaseAddress; + MPU_InitStruct.Size = MpuAreas[mpu_region_num].Size; + MPU_InitStruct.SubRegionDisable = MpuAreas[mpu_region_num].SubRegionDisable; + MPU_InitStruct.AccessPermission = MpuAreas[mpu_region_num].AccessPermission; + MPU_InitStruct.DisableExec = MpuAreas[mpu_region_num].DisableExec; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE(" @%d:%x size:%x sub:%x perm:%x exec:%x\r\n", + MPU_InitStruct.Number, MPU_InitStruct.BaseAddress, MPU_InitStruct.Size, MPU_InitStruct.SubRegionDisable, + MPU_InitStruct.AccessPermission, MPU_InitStruct.DisableExec); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + if (uStep == SFU_INITIAL_CONFIGURATION) + { + HAL_MPU_ConfigRegion(&MPU_InitStruct); + } + else + { + if (MPU_CheckConfig(&MPU_InitStruct) == SFU_ERROR) + { + return SFU_ERROR; + } + } + } + + if (uStep == SFU_INITIAL_CONFIGURATION) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + /* Enables the MPU */ + HAL_MPU_Enable(MPU_HARDFAULT_NMI); + +#if defined(SCB_SHCSR_MEMFAULTENA_Msk) + /* Enables memory fault exception */ + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif /* SCB_SHCSR_MEMFAULTENA_Msk */ + } + else + { + if (MPU->CTRL != (MPU_HARDFAULT_NMI | MPU_CTRL_ENABLE_Msk)) + { + return SFU_ERROR; + } +#if defined(SCB_SHCSR_MEMFAULTENA_Msk) + if ((SCB->SHCSR & SCB_SHCSR_MEMFAULTENA_Msk) != SCB_SHCSR_MEMFAULTENA_Msk) + { + return SFU_ERROR; + } +#endif /* SCB_SHCSR_MEMFAULTENA_Msk */ + } + + e_ret_status = SFU_SUCCESS; + + + if (e_ret_status == SFU_SUCCESS) + { + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_MPU, FLOW_CTRL_MPU); + } + return e_ret_status; +} +#endif /*SFU_MPU_PROTECT_ENABLE*/ + + + +#ifdef SFU_DMA_PROTECT_ENABLE +/** + * @brief Apply DMA protection + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionDMA(void) +{ + /* + * In this function we disable the DMA buses in order to avoid that while the SB/SFU is running + * some DMA has been already enabled (e.g. through debugger in RDP-1 after reset) in order to access sensitive + * information in SRAM, FLASH + */ + /* Disable DMA1, DMA2 */ + __HAL_RCC_DMA1_CLK_DISABLE(); + + __HAL_RCC_DMA2_CLK_DISABLE(); + + __HAL_RCC_DMAMUX1_CLK_DISABLE(); + + + + + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_DMA, FLOW_CTRL_DMA); + return SFU_SUCCESS; +} +#endif /*SFU_DMA_PROTECT_ENABLE*/ + +#ifdef SFU_IWDG_PROTECT_ENABLE +/** + * @brief Apply IWDG protection + * The IWDG timeout is set to 4 second. + * Then, the IWDG reload counter is configured as below to obtain 4 second according + * to the measured LSI frequency after setting the prescaler value: + * IWDG counter clock Frequency = LSI Frequency / Prescaler value + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionIWDG(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* TIMER could be used to get the LSI frequency in order to have a more precise IWDG. + This is not used in this implementation because not necessary and in order + to optimize code-size. If you are interested, please have a look at the IWDG Cube example. */ + + /* Configure & Start the IWDG peripheral */ + /* Set counter reload value to obtain 6 sec. IWDG TimeOut. + IWDG counter clock Frequency = uwLsiFreq + Set Prescaler to 64 (IWDG_PRESCALER_64) + Timeout Period = (Reload Counter Value * 64) / uwLsiFreq + So Set Reload Counter Value = (6 * uwLsiFreq) / 64 */ + IwdgHandle.Instance = IWDG; + IwdgHandle.Init.Prescaler = IWDG_PRESCALER_64; + IwdgHandle.Init.Reload = (SFU_IWDG_TIMEOUT * LSI_VALUE / 64U); + IwdgHandle.Init.Window = IWDG_WINDOW_DISABLE; + + if (HAL_IWDG_Init(&IwdgHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_IWDG, FLOW_CTRL_IWDG); + } + + return e_ret_status; +} +#endif /*SFU_IWDG_PROTECT_ENABLE*/ + +#ifdef SFU_DAP_PROTECT_ENABLE +/** + * @brief Set DAP protection status, configuring SWCLK and SWDIO GPIO pins. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionDAP(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable clock of DBG GPIO port */ + SFU_DBG_CLK_ENABLE(); + + /* Enable the DAP protections, so disable the DAP re-configuring SWCLK and SWDIO GPIO pins */ + GPIO_InitStruct.Pin = SFU_DBG_SWDIO_PIN | SFU_DBG_SWCLK_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(SFU_DBG_PORT, &GPIO_InitStruct); + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_DAP, FLOW_CTRL_DAP); + + return e_ret_status; +} +#else +#endif /*SFU_DAP_PROTECT_ENABLE*/ + +#ifdef SFU_TAMPER_PROTECT_ENABLE +/** + * @brief Apply ANTI TAMPER protection + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionANTI_TAMPER(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + RTC_TamperTypeDef stamperstructure; + + /* RTC_TAMPER_1 (PC13) selected. PA0 connected to RTC_TAMPER_2 is also connected to the B1 button */ + TAMPER_GPIO_CLK_ENABLE(); + + /* Configure Tamper Pin */ + /* tamper is an additional function */ + /* not an alternate Function : config not needed */ + /* Configure the RTC peripheral */ + /* Configure RTC prescaler and RTC data registers */ + /* RTC configured as follows: + - Hour Format = Format 24 + - Asynch Prediv = Value according to source clock + - Synch Prediv = Value according to source clock + - OutPut = Output Disable + - OutPutPolarity = High Polarity + - OutPutType = Open Drain */ + RtcHandle.Instance = RTC; + RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; + RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; + RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; + RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; + RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + + if (HAL_RTC_Init(&RtcHandle) == HAL_OK) + { + /* Configure RTC Tamper */ + stamperstructure.Tamper = RTC_TAMPER_ID; + stamperstructure.Trigger = RTC_TAMPERTRIGGER_FALLINGEDGE; + stamperstructure.Filter = RTC_TAMPERFILTER_DISABLE; + stamperstructure.SamplingFrequency = RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768; + stamperstructure.PrechargeDuration = RTC_TAMPERPRECHARGEDURATION_1RTCCLK; + stamperstructure.TamperPullUp = RTC_TAMPER_PULLUP_ENABLE; + stamperstructure.TimeStampOnTamperDetection = RTC_TIMESTAMPONTAMPERDETECTION_DISABLE; + stamperstructure.NoErase = RTC_TAMPER_ERASE_BACKUP_ENABLE; + stamperstructure.MaskFlag = RTC_TAMPERMASK_FLAG_DISABLE; + + if (HAL_RTCEx_SetTamper_IT(&RtcHandle, &stamperstructure) == HAL_OK) + { + + /* Clear the Tamper interrupt pending bit */ + __HAL_RTC_TAMPER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_TAMP_1); + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_TAMPER, FLOW_CTRL_TAMPER); + } + } + + return e_ret_status; +} +#endif /*SFU_TAMPER_PROTECT_ENABLE*/ + +#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE +/** + * @brief Apply CLOCK MONITOR protection + * @note This function has been added just as template to be used/customized + * if a clock monitor is requested. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionCLOCK_MONITOR(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Apply the Clock Monitoring */ + /* Add your code here for customization + e.g. if HSE or LSE is used enable the CSS! + ... + ... + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} +#endif /*SFU_CLCK_MNTR_PROTECT_ENABLE*/ + +#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE +/** + * @brief Apply TEMP MONITOR protection + * @note This function has been added just as template to be used/customized + * if a temperature monitor is requested. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionTEMP_MONITOR(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Apply the Temperature Monitoring */ + /* Add your code here for customization + ... + ... + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} +#endif /*SFU_TEMP_MNTR_PROTECT_ENABLE*/ + + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_security.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_security.h new file mode 100644 index 00000000..91ab2aa8 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/BFU/Target/sfu_low_level_security.h @@ -0,0 +1,288 @@ +/** + ****************************************************************************** + * @file sfu_low_level_security.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update security + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_SECURITY_H +#define SFU_LOW_LEVEL_SECURITY_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_fwimg_regions.h" +#include "sfu_def.h" + +/* Exported constants --------------------------------------------------------*/ + +/*!< Bank 1, Area A used to protect Vector Table */ +#define SFU_PROTECT_WRP_AREA_1 (OB_WRPAREA_BANK1_AREAA) + +/*!< First page including the Vector Table: 0 based */ +#define SFU_PROTECT_WRP_PAGE_START_1 ((uint32_t)((SFU_BOOT_BASE_ADDR - FLASH_BASE) / FLASH_PAGE_SIZE)) + +/*!< Last page: (code_size-1)/page_size because the page + indexes start from 0 */ +#define SFU_PROTECT_WRP_PAGE_END_1 ((uint32_t)((SFU_ROM_ADDR_END - FLASH_BASE) / FLASH_PAGE_SIZE)) + + + +/** + * @brief The regions can overlap, and can be nested. The region 7 has the highest priority + * and the region 0 has the lowest one and this governs how overlapping the regions behave. + * The priorities are fixed, and cannot be changed. + */ + + +/** + * @brief Region 0 - The Aliases Region and all User Flash & internal RAM. When executing inside SB/SFU by default all + * the Aliases and all the User Flash (used for UserApp1 and UserApp2) area must not be executable, + * but used only to read and write the downloaded code RAM is also not executable. + * From this full Area we'll enable the Execution permission only on the SB/SFU Flash Area. + */ + +#define SFU_PROTECT_MPU_AREA_USER_START ((uint32_t)0x00000000U) +#define SFU_PROTECT_MPU_AREA_USER_SIZE MPU_REGION_SIZE_1GB /*!< up to 0x3FFFFFFF */ +#define SFU_PROTECT_MPU_AREA_USER_PERM MPU_REGION_FULL_ACCESS +#define SFU_PROTECT_MPU_AREA_USER_EXEC MPU_INSTRUCTION_ACCESS_DISABLE +#define SFU_PROTECT_MPU_AREA_USER_SREG 0x00U /*!< All subregions activated */ + +/** + * @brief Region 1 and Region 2 - Enable the execution for SB/SFU Full area (SBSFU + SE + Keys). Inner region inside + * the Region 0 + */ +#define SFU_PROTECT_MPU_MAX_NB_SUBREG (8U) /*!< 8 sub-regions is the maximum */ +#define SFU_PROTECT_MPU_AREA_SFUEN_START_0 FLASH_BASE +#define SFU_PROTECT_MPU_AREA_SFUEN_START_1 0x0800C000 +#define SFU_PROTECT_MPU_AREA_SFUEN_SIZE_0 MPU_REGION_SIZE_64KB +#define SFU_PROTECT_MPU_AREA_SFUEN_SIZE_1 MPU_REGION_SIZE_4KB +#define SFU_PROTECT_MPU_AREA_SFUEN_PERM MPU_REGION_FULL_ACCESS +#define SFU_PROTECT_MPU_AREA_SFUEN_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#if defined(__GNUC__) +#define SFU_PROTECT_MPU_AREA_SFUEN_SREG_0 0x80U /*!< 64 bytes / 8 * 7 ==> 56 bytes */ +#else /* __GNUC__ */ +#define SFU_PROTECT_MPU_AREA_SFUEN_SREG_0 0xC0U /*!< 64 bytes / 8 * 6 ==> 48 bytes */ +#endif /* __GNUC__ */ +#define SFU_PROTECT_MPU_AREA_SFUEN_SREG_1 0x00U /*!< All subregions activated */ + +/** + * @brief Region 3 - Vector Table: Vector Table must be Read-Only under privileged access. Inner region inside the + * Region 1 + */ +#define SFU_PROTECT_MPU_AREA_VECT_START ((uint32_t) INTVECT_START) /*!< Vector table memory area */ +#define SFU_PROTECT_MPU_AREA_VECT_SIZE MPU_REGION_SIZE_512B +#define SFU_PROTECT_MPU_AREA_VECT_PERM MPU_REGION_PRIV_RO +#define SFU_PROTECT_MPU_AREA_VECT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#define SFU_PROTECT_MPU_AREA_VECT_SREG 0x00U /*!< All subregions activated */ + +/** + * @brief Region 4 - Inner region inside the Region 0 . The Option Bytes. Once the Option Bytes have been set, + * only reading will be possible + */ + +/* + * WLxx + * Single Bank + * [ 1FFF7800 1FFF7808 1FFF7810 1FFF7818 1FFF7820]: 40 bytes to be protected + * The MPU can be used to protect up to eight memory regions. + * These, in turn can have eight subregions, if the region is at least 256 bytes. + * Here, we define a 64B region so subregions cannot be used. + */ +#define SFU_PROTECT_MPU_AREA_OB_BANK1_START ((uint32_t)0x1FFF7800U) /*!< Option Bytes in bank 1 */ +#define SFU_PROTECT_MPU_AREA_OB_BANK1_SIZE MPU_REGION_SIZE_64B /*!< Protecting more than required */ +#define SFU_PROTECT_MPU_AREA_OB_BANK1_PERM MPU_REGION_NO_ACCESS +#define SFU_PROTECT_MPU_AREA_OB_BANK1_EXEC MPU_INSTRUCTION_ACCESS_DISABLE +#define SFU_PROTECT_MPU_AREA_OB_BANK1_SREG 0x00U /*!< Subregion mask to deactivate unexpected + MPU subregions: 0x1F should be set but it + would have no effect as we have a 64B + region */ + +/** + * @brief Region 5 - Peripherals Area + */ +#define SFU_PROTECT_MPU_AREA_PERIPH_START PERIPH_BASE /*!< Peripheral memory area */ +#define SFU_PROTECT_MPU_AREA_PERIPH_SIZE MPU_REGION_SIZE_512MB /*!< To be coherent with the peripherals + memory area */ +#define SFU_PROTECT_MPU_AREA_PERIPH_PERM MPU_REGION_FULL_ACCESS +#define SFU_PROTECT_MPU_AREA_PERIPH_EXEC MPU_INSTRUCTION_ACCESS_DISABLE +#define SFU_PROTECT_MPU_AREA_PERIPH_SREG 0x00U /*!< All subregions activated */ + + +/** + * MPU configuration for UserApp execution + * ======================================= + * @brief Region 6 & 7 - Enable the execution of the active slots + * MPU constraint = Region base address should be aligned on Region size + */ +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) +/** + * Region definition : from 0x0801 0000 ==> 0x0801 07FF (remove 2 kbytes) + */ +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_START SLOT_BLOB_DWL_1_START +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SIZE MPU_REGION_SIZE_2KB +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_PERM MPU_REGION_FULL_ACCESS +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_EXEC MPU_INSTRUCTION_ACCESS_DISABLE +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SREG 0x00U /*!< All subregions activated */ +#else /* __GNUC__ && !__ARMCC_VERSION */ +/** + * Region definition : from 0x0800 F800 ==> 0x0800 FFFF (2 kbytes) + */ +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_START SLOT_ACTIVE_1_START +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SIZE MPU_REGION_SIZE_2KB +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_PERM MPU_REGION_FULL_ACCESS +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SREG 0x00U /*!< All subregions activated */ +#endif /* __GNUC__ && !__ARMCC_VERSION */ +/** + * Additional Region definition : from 0x0801 0000 ==> 0x0803 FFFF (192 kbytes) + */ +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_START FLASH_BASE +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SIZE MPU_REGION_SIZE_256KB +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_PERM MPU_REGION_FULL_ACCESS +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SREG 0x03U /*!< 256 Kbytes / 8 * 6 ==> 192 Kbytes */ + + +/** + * @} + */ + +/** @defgroup SFU_CONFIG_TAMPER Tamper Configuration + * @{ + */ +#define TAMPER_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define RTC_TAMPER_ID RTC_TAMPER_1 +#define RTC_TAMPER_ID_INTERRUPT RTC_IT_TAMP_1 + +/** + * @} + */ + +/** @defgroup SFU_CONFIG_DBG Debug Port Configuration + * @{ + */ +#define SFU_DBG_PORT GPIOA +#define SFU_DBG_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_DBG_SWDIO_PIN GPIO_PIN_13 +#define SFU_DBG_SWCLK_PIN GPIO_PIN_14 + + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SFU_SECURITY_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup SFU_SECURITY_Exported_Constants_Wakeup FU WAKEUP ID Type definition + * @{ + */ +typedef enum +{ + SFU_RESET_UNKNOWN = 0x00U, + SFU_RESET_WDG_RESET, + SFU_RESET_LOW_POWER, + SFU_RESET_HW_RESET, + SFU_RESET_BOR_RESET, + SFU_RESET_SW_RESET, + SFU_RESET_OB_LOADER, +} SFU_RESET_IdTypeDef; + +/** + * @} + */ + +/** @defgroup SFU_SECURITY_Exported_Constants_Protections FU SECURITY Protections_Constants + * @{ + */ +#define SFU_PROTECTIONS_NONE ((uint32_t)0x00000000U) /*!< Protection configuration unchanged */ +#define SFU_STATIC_PROTECTION_RDP ((uint32_t)0x00000001U) /*!< RDP protection level 1 is applied */ +#define SFU_STATIC_PROTECTION_WRP ((uint32_t)0x00000002U) /*!< Constants section in Flash. Needed as + separate section to support PCRoP */ +#define SFU_STATIC_PROTECTION_PCROP ((uint32_t)0x00000004U) /*!< SFU App section in Flash */ +#define SFU_STATIC_PROTECTION_LOCKED ((uint32_t)0x00000008U) /*!< RDP Level2 is applied. The device is Locked! + Std Protections cannot be + added/removed/modified */ +#define SFU_STATIC_PROTECTION_BFB2 ((uint32_t)0x00000010U) /*!< BFB2 is disabled. The device shall always + boot in bank1! */ + +#define SFU_RUNTIME_PROTECTION_MPU ((uint32_t)0x00000100U) /*!< Shared Info section in Flash */ +#define SFU_RUNTIME_PROTECTION_IWDG ((uint32_t)0x00000400U) /*!< Independent Watchdog */ +#define SFU_RUNTIME_PROTECTION_DAP ((uint32_t)0x00000800U) /*!< Debug Access Port control */ +#define SFU_RUNTIME_PROTECTION_DMA ((uint32_t)0x00001000U) /*!< DMA protection, disable DMAs */ +#define SFU_RUNTIME_PROTECTION_ANTI_TAMPER ((uint32_t)0x00002000U) /*!< Anti-Tampering protections */ +#define SFU_RUNTIME_PROTECTION_CLOCK_MONITOR ((uint32_t)0x00004000U) /*!< Activate a clock monitoring */ +#define SFU_RUNTIME_PROTECTION_TEMP_MONITOR ((uint32_t)0x00008000U) /*!< Activate a Temperature monitoring */ + +#define SFU_STATIC_PROTECTION_ALL (SFU_STATIC_PROTECTION_RDP | SFU_STATIC_PROTECTION_WRP | \ + SFU_STATIC_PROTECTION_PCROP | SFU_STATIC_PROTECTION_LOCKED) +/*!< All the static protections */ + +#define SFU_RUNTIME_PROTECTION_ALL (SFU_RUNTIME_PROTECTION_MPU | SFU_RUNTIME_PROTECTION_FWALL | \ + SFU_RUNTIME_PROTECTION_IWDG | SFU_RUNTIME_PROTECTION_DAP | \ + SFU_RUNTIME_PROTECTION_DMA | SFU_RUNTIME_PROTECTION_ANTI_TAMPER | \ + SFU_RUNTIME_PROTECTION_CLOCK_MONITOR | SFU_RUNTIME_PROTECTION_TEMP_MONITOR) +/*!< All the run-time protections */ + +#define SFU_INITIAL_CONFIGURATION (0x00U) /*!< Initial configuration */ +#define SFU_SECOND_CONFIGURATION (0x01U) /*!< Second configuration */ +#define SFU_THIRD_CONFIGURATION (0x02U) /*!< Third configuration */ + +/* Exported functions ------------------------------------------------------- */ +#define SFU_CALLBACK_ANTITAMPER HAL_RTCEx_Tamper1EventCallback +/*!
      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.
      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_HW_H +#define APP_HW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported macros -----------------------------------------------------------*/ +/* At power-on, the capacitor related to SW1 button needs to charge. + * The charging time must be waited to be sure that a low level is a real one. */ +#define BUTTON_INIT() \ + BSP_PB_Init(BUTTON_SW1,BUTTON_MODE_GPIO); \ + if ((uint32_t) BSP_PB_GetState(BUTTON_SW1) == (uint32_t)GPIO_PIN_RESET) \ + { \ + HAL_Delay(6U); \ + } + +#define BUTTON_PUSHED() ((uint32_t) BSP_PB_GetState(BUTTON_SW1) == (uint32_t)GPIO_PIN_RESET) + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_HW_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/main.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/main.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/main.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/main.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/stm32wlxx_it.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/stm32wlxx_it.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Inc/stm32wlxx_it.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/stm32wlxx_it.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h new file mode 100644 index 00000000..0af7b23e --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * @file stm32wlxx_nucleo_conf.h + * @author MCD Application Team + * @brief STM32WLxx_Nucleo board configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2020(-2021) STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLXX_NUCLEO_CONF_H +#define STM32WLXX_NUCLEO_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wlxx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WLXX_NUCLEO + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG CONFIG + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG_Exported_Constants Exported Constants + * @{ + */ +/* COM usage define */ +#define USE_BSP_COM_FEATURE 0U + +/* COM log define */ +#define USE_COM_LOG 0U + +/* IRQ priorities */ +#define BSP_BUTTON_SWx_IT_PRIORITY 15U + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLXX_NUCLEO_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/main.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/main.c new file mode 100644 index 00000000..8891771b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/main.c @@ -0,0 +1,157 @@ +/** + ****************************************************************************** + * @file main.c + * @author MCD Application Team + * @brief Main application file. + * This application demonstrates Secure Boot and Secure Firmware Update. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_boot.h" + + +/* Private variables ---------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief main function + * @param None + * @retval int + */ +int main(void) +{ + + /* MCU Configuration--------------------------------------------------------*/ + /* Configure the system clock using LL functions */ + SystemClock_Config(); + + /* This part is NOT secure (security mechanisms NOT enabled yet) */ + /* Reset of all peripherals, Initializes the Flash interface and the Systick*/ + (void) HAL_Init(); + + /* Board BSP Configuration-------------------------------------------------*/ + /* + * As the secure mode has not been entered yet, we do not configure BSP right now . + * The BSP will be configured by the bootloader. + */ + + + /* Launch the Bootloader----------------------------------------------------*/ + /* + * This is the beginning of the secure part: + * security mechanisms will be enabled. + * The function below should not return (unless a critical failure is encountered). + */ + (void)SFU_BOOT_RunSecureBootService(); /* no need to take care of the returned value as we reboot in all cases */ + + /* Security or SecureBoot initialization failure. Force a System Reset */ + SFU_BOOT_ForceReboot(); + +} + +/** + * @brief System Clock Configuration + * The system Clock is configured as follows : + * System Clock source = PLL (MSI) + * SYSCLK(Hz) = 48000000 + * HCLK(Hz) = 48000000 + * AHB1 Prescaler = 1 + * AHB3 Prescaler = 1 + * APB1 Prescaler = 1 + * APB2 Prescaler = 1 + * MSI Frequency(Hz) = 4000000 + * PLL_M = 1 + * PLL_N = 24 + * PLL_R = 2 + * Flash Latency(WS) = 2 + * Voltage range = 1 + * @param None + * @retval None + */ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_2); + + while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) + { + }; + + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); + LL_RCC_MSI_Enable(); + + /* Wait till MSI is ready */ + while(LL_RCC_MSI_IsReady() != 1) + { + }; + + LL_RCC_MSI_EnableRangeSelection(); + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6); + LL_RCC_MSI_SetCalibTrimming(0); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 24, LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_EnableDomain_SYS(); + LL_RCC_PLL_Enable(); + + /* Wait till PLL is ready */ + while(LL_RCC_PLL_IsReady() != 1) + { + }; + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + + /* Wait till System clock is ready */ + while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) + { + }; + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAHB3Prescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + + LL_Init1msTick(48000000); + + /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */ + LL_SetSystemCoreClock(48000000); +} + + + + + +#ifdef USE_FULL_ASSERT + +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ + +} + +#endif /* USE_FULL_ASSERT */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/stm32wlxx_it.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/stm32wlxx_it.c new file mode 100644 index 00000000..b68f7c5a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/Core/Src/stm32wlxx_it.c @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * @file stm32wlxx_it.c + * @author MCD Application Team + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32wlxx_it.h" + +/* Global variables ----------------------------------------------------------*/ +/* RTC handler declaration */ +RTC_HandleTypeDef RtcHandle; + +/* Functions Definition ------------------------------------------------------*/ +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ + +/* Exception handlers are implemented in the various source files of sbsfu application */ + +/* NMI exception handler is implemented in sfu_low_level_flash_int.c file */ +/* Hard Fault exception handler is implemented in sfu_boot.c file */ +/* Memory Manage exception handler is implemented in sfu_boot.c file */ +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +void SVC_Handler(void) +{ +} + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +void PendSV_Handler(void) +{ +} + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +void SysTick_Handler(void) +{ + HAL_IncTick(); +} + +/******************************************************************************/ +/* STM32WLxx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32wlxx.s). */ +/******************************************************************************/ +#ifdef SFU_TAMPER_PROTECT_ENABLE +/** + * @brief This function handles Tamper interrupt request. + * @param None + * @retval None + */ +void TAMP_STAMP_LSECSS_SSRU_IRQHandler() +{ + HAL_RTCEx_TamperIRQHandler(&RtcHandle); +} +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + + + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/Project.ewd similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/Project.ewd rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/Project.ewd diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/Project.ewp new file mode 100644 index 00000000..fc340dac --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/Project.ewp @@ -0,0 +1,1229 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_BFU + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + $TOOLKIT_DIR$\bin\isymexport.exe --edit "$PROJ_DIR$\steering_file.txt" "$TARGET_PATH$" "$PROJ_DIR$\se_interface_appli.o" + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + Core + + $PROJ_DIR$\..\Core\Src\main.c + + + $PROJ_DIR$\..\Core\Src\stm32wlxx_hal_msp.c + + + $PROJ_DIR$\..\Core\Src\stm32wlxx_it.c + + + + BFU + + App + + $PROJ_DIR$\..\BFU\App\sfu_loader.c + + + $PROJ_DIR$\..\BFU\App\sfu_boot.c + + + $PROJ_DIR$\..\BFU\App\sfu_com_loader.c + + + $PROJ_DIR$\..\BFU\App\sfu_com_trace.c + + + $PROJ_DIR$\..\BFU\App\sfu_error.c + + + $PROJ_DIR$\..\BFU\App\sfu_test.c + + + $PROJ_DIR$\..\BFU\App\sfu_fwimg_common.c + + + $PROJ_DIR$\..\BFU\App\sfu_new_image.c + + + $PROJ_DIR$\..\BFU\App\sfu_kms.c + + + $PROJ_DIR$\..\BFU\App\sfu_interface_crypto_scheme.c + + + + Target + + $PROJ_DIR$\..\BFU\Target\sfu_low_level.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash_int.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash_ext.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_security.c + + + + + EWARM + + $PROJ_DIR$\startup_stm32wl55xx_cm4.s + + + + + Drivers + + BSP + + STM32WLxx_Nucleo + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\BSP\STM32WLxx_Nucleo\stm32wlxx_nucleo.c + + + + + STM32WLxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cortex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_iwdg.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_exti.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c + + + + STM32WLxx_LL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_ll_utils.c + + + + CMSIS + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\CMSIS\Device\ST\STM32WLxx\Source\Templates\system_stm32wlxx.c + + + + + Middlewares + + STM32_Secure_Engine + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_application.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_bootloader.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_common.c + + + + STM32_Key_Management_Services + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\iKMS\se_interface_kms.c + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s new file mode 100644 index 00000000..658ca8e5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s @@ -0,0 +1,509 @@ +;******************************************************************************** +;* File Name : startup_stm32wl55xx_cm4.s +;* Author : MCD Application Team +;* Description : M4 core vector table of the STM32WLxxxx devices for the +;* IAR (EWARM) toolchain. +;* +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* +;* Copyright (c) 2020(2021) STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +; +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD and PVM Interrupt + DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSRU Interrupts + DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt + DCD FLASH_IRQHandler ; FLASH global Interrupt + DCD RCC_IRQHandler ; RCC Interrupt + DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt + DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt + DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt + DCD EXTI3_IRQHandler ; EXTI Line 3 Interrupt + DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt + DCD ADC_IRQHandler ; ADC Interrupt + DCD DAC_IRQHandler ; DAC Interrupt + DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV Interrupt + DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts + DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt + DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt + DCD TIM2_IRQHandler ; TIM2 Global Interrupt + DCD TIM16_IRQHandler ; TIM16 Global Interrupt + DCD TIM17_IRQHandler ; TIM17 Global Interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt + DCD SPI1_IRQHandler ; SPI1 Interrupt + DCD SPI2_IRQHandler ; SPI2 Interrupt + DCD USART1_IRQHandler ; USART1 Interrupt + DCD USART2_IRQHandler ; USART2 Interrupt + DCD LPUART1_IRQHandler ; LPUART1 Interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 Global Interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 Global Interrupt + DCD EXTI15_10_IRQHandler ; EXTI Lines [15:10] Interrupt + DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 Global Interrupt + DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt + DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt + DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt + DCD HSEM_IRQHandler ; HSEM0 Interrupt + DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt + DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt + DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt + DCD AES_IRQHandler ; AES Interrupt + DCD RNG_IRQHandler ; RNG1 Interrupt + DCD PKA_IRQHandler ; PKA Interrupt + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt + DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_PVM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_PVM_IRQHandler + B PVD_PVM_IRQHandler + + PUBWEAK TAMP_STAMP_LSECSS_SSRU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_STAMP_LSECSS_SSRU_IRQHandler + B TAMP_STAMP_LSECSS_SSRU_IRQHandler + + PUBWEAK RTC_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_WKUP_IRQHandler + B RTC_WKUP_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel2_IRQHandler + B DMA1_Channel2_IRQHandler + + PUBWEAK DMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel3_IRQHandler + B DMA1_Channel3_IRQHandler + + PUBWEAK DMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel4_IRQHandler + B DMA1_Channel4_IRQHandler + + PUBWEAK DMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel5_IRQHandler + B DMA1_Channel5_IRQHandler + + PUBWEAK DMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel6_IRQHandler + B DMA1_Channel6_IRQHandler + + PUBWEAK DMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel7_IRQHandler + B DMA1_Channel7_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK DAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC_IRQHandler + B DAC_IRQHandler + + PUBWEAK C2SEV_PWR_C2H_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +C2SEV_PWR_C2H_IRQHandler + B C2SEV_PWR_C2H_IRQHandler + + PUBWEAK COMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP_IRQHandler + B COMP_IRQHandler + + PUBWEAK EXTI9_5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_5_IRQHandler + B EXTI9_5_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK EXTI15_10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_10_IRQHandler + B EXTI15_10_IRQHandler + + PUBWEAK RTC_Alarm_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Alarm_IRQHandler + B RTC_Alarm_IRQHandler + + PUBWEAK LPTIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM3_IRQHandler + B LPTIM3_IRQHandler + + PUBWEAK SUBGHZSPI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZSPI_IRQHandler + B SUBGHZSPI_IRQHandler + + PUBWEAK IPCC_C1_RX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_RX_IRQHandler + B IPCC_C1_RX_IRQHandler + + PUBWEAK IPCC_C1_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_TX_IRQHandler + B IPCC_C1_TX_IRQHandler + + PUBWEAK HSEM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HSEM_IRQHandler + B HSEM_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK SUBGHZ_Radio_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZ_Radio_IRQHandler + B SUBGHZ_Radio_IRQHandler + + PUBWEAK AES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AES_IRQHandler + B AES_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK PKA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PKA_IRQHandler + B PKA_IRQHandler + + PUBWEAK DMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel1_IRQHandler + B DMA2_Channel1_IRQHandler + + PUBWEAK DMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel2_IRQHandler + B DMA2_Channel2_IRQHandler + + PUBWEAK DMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel3_IRQHandler + B DMA2_Channel3_IRQHandler + + PUBWEAK DMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel4_IRQHandler + B DMA2_Channel4_IRQHandler + + PUBWEAK DMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel5_IRQHandler + B DMA2_Channel5_IRQHandler + + PUBWEAK DMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel6_IRQHandler + B DMA2_Channel6_IRQHandler + + PUBWEAK DMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel7_IRQHandler + B DMA2_Channel7_IRQHandler + + PUBWEAK DMAMUX1_OVR_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMAMUX1_OVR_IRQHandler + B DMAMUX1_OVR_IRQHandler + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/steering_file.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/steering_file.txt new file mode 100644 index 00000000..8349caff --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/steering_file.txt @@ -0,0 +1,37 @@ +show SE_APP_GetActiveFwInfo +show SE_KMS_Initialize +show SE_KMS_Finalize +show SE_KMS_GetInfo +show SE_KMS_GetFunctionList +show SE_KMS_GetSlotList +show SE_KMS_GetSlotInfo +show SE_KMS_GetTokenInfo +show SE_KMS_GetMechanismInfo +show SE_KMS_OpenSession +show SE_KMS_CloseSession +show SE_KMS_CreateObject +show SE_KMS_DestroyObject +show SE_KMS_GetAttributeValue +show SE_KMS_SetAttributeValue +show SE_KMS_FindObjectsInit +show SE_KMS_FindObjects +show SE_KMS_FindObjectsFinal +show SE_KMS_EncryptInit +show SE_KMS_Encrypt +show SE_KMS_EncryptUpdate +show SE_KMS_EncryptFinal +show SE_KMS_DecryptInit +show SE_KMS_Decrypt +show SE_KMS_DecryptUpdate +show SE_KMS_DecryptFinal +show SE_KMS_DigestInit +show SE_KMS_Digest +show SE_KMS_DigestUpdate +show SE_KMS_DigestFinal +show SE_KMS_SignInit +show SE_KMS_Sign +show SE_KMS_VerifyInit +show SE_KMS_Verify +show SE_KMS_DeriveKey +show SE_KMS_GenerateKeyPair +show SE_KMS_GenerateRandom diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/stm32wl55xx_flash_cm4.icf similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/EWARM/stm32wl55xx_flash_cm4.icf rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/EWARM/stm32wl55xx_flash_cm4.icf diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/BFU.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/BFU.sct similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/BFU.sct rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/BFU.sct diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/Project.uvoptx similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/Project.uvoptx rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/Project.uvoptx diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..3888d591 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/Project.uvprojx @@ -0,0 +1,698 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_BFU + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + BFU + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf #L --bincombined --output=$L@L.bin + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + -Wno-format + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED + + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../Core/Inc;../BFU/App;../BFU/Target;../../1_Image_SECoreBin/Inc;../../Linker_Common/MDK-ARM;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../../../../../Middlewares/ST/STM32_Secure_Engine/Interface;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS;../../../../../../Drivers/BSP/STM32WLxx_Nucleo + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + BFU.sct + + + --symdefs=se_interface_appli.txt +--keep=SE_CORE_Bin.o(SE_CORE_Bin) + + + + + + + + Application/Core + + + main.c + 1 + ../Core/Src/main.c + + + stm32wlxx_hal_msp.c + 1 + ../Core/Src/stm32wlxx_hal_msp.c + + + stm32wlxx_it.c + 1 + ../Core/Src/stm32wlxx_it.c + + + + + Application/MDK-ARM + + + se_core_bin.s + 2 + se_core_bin.s + + + startup_stm32wl55xx_cm4.s + 2 + startup_stm32wl55xx_cm4.s + + + + + Application/BFU/App + + + sfu_boot.c + 1 + ../BFU/App/sfu_boot.c + + + sfu_com_loader.c + 1 + ..\BFU\App\sfu_com_loader.c + + + sfu_com_trace.c + 1 + ..\BFU\App\sfu_com_trace.c + + + sfu_error.c + 1 + ../BFU/App/sfu_error.c + + + sfu_fwimg_common.c + 1 + ../BFU/App/sfu_fwimg_common.c + + + sfu_interface_crypto_scheme.c + 1 + ../BFU/App/sfu_interface_crypto_scheme.c + + + sfu_kms.c + 1 + ../BFU/App/sfu_kms.c + + + sfu_loader.c + 1 + ..\BFU\App\sfu_loader.c + + + sfu_new_image.c + 1 + ..\BFU\App\sfu_new_image.c + + + sfu_test.c + 1 + ../BFU/App/sfu_test.c + + + + + Application/BFU/Target + + + sfu_low_level.c + 1 + ..\BFU\Target\sfu_low_level.c + + + sfu_low_level_flash.c + 1 + ..\BFU\Target\sfu_low_level_flash.c + + + sfu_low_level_flash_ext.c + 1 + ..\BFU\Target\sfu_low_level_flash_ext.c + + + sfu_low_level_flash_int.c + 1 + ..\BFU\Target\sfu_low_level_flash_int.c + + + sfu_low_level_security.c + 1 + ../BFU/Target/sfu_low_level_security.c + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Drivers/BSP/STM32WLxx_Nucleo + + + stm32wlxx_nucleo.c + 1 + ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + + + Drivers/STM32WLxx_HAL_Driver + + + stm32wlxx_hal.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + stm32wlxx_hal_cortex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + stm32wlxx_hal_crc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + stm32wlxx_hal_crc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + stm32wlxx_hal_dma.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + + + stm32wlxx_hal_flash.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + stm32wlxx_hal_flash_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + stm32wlxx_hal_gpio.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + stm32wlxx_hal_iwdg.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + stm32wlxx_hal_pwr.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + stm32wlxx_hal_pwr_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + stm32wlxx_hal_rcc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + stm32wlxx_hal_rcc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + stm32wlxx_hal_rtc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + stm32wlxx_hal_rtc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + stm32wlxx_hal_spi.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi.c + + + stm32wlxx_hal_spi_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi_ex.c + + + stm32wlxx_hal_tim.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim.c + + + stm32wlxx_hal_tim_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim_ex.c + + + stm32wlxx_hal_uart.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + stm32wlxx_hal_uart_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + stm32wlxx_hal_exti.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + + + Drivers/CMSIS + + + system_stm32wlxx.c + 1 + ../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Source/Templates/system_stm32wlxx.c + + + + + Middlewares/STM32_Secure_Engine + + + se_interface_application.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_application.c + + + se_interface_bootloader.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_bootloader.c + + + se_interface_common.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_common.c + + + + + Middlewares/STM32_Key_Management_Services + + + se_interface_kms.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS/se_interface_kms.c + + + + + Drivers/STM32WLxx_LL_Driver + + + stm32wlxx_ll_utils.c + 1 + ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_ll_utils.c + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/STM32WL55JC_Nucleo/Exe/se_interface_appli.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/STM32WL55JC_Nucleo/Exe/se_interface_appli.txt similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/STM32WL55JC_Nucleo/Exe/se_interface_appli.txt rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/STM32WL55JC_Nucleo/Exe/se_interface_appli.txt diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/se_core_bin.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/se_core_bin.s similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/se_core_bin.s rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/se_core_bin.s diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/startup_stm32wl55xx_cm4.s similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/MDK-ARM/startup_stm32wl55xx_cm4.s rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/MDK-ARM/startup_stm32wl55xx_cm4.s diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/.cproject new file mode 100644 index 00000000..635041a5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/.cproject @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/.project new file mode 100644 index 00000000..c2f439f1 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/.project @@ -0,0 +1,271 @@ + + + 1_Image_BFU + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doc/readme.txt + 1 + $%7BPARENT-1-PROJECT_LOC%7D/readme.txt + + + Application/Core/main.c + 1 + PARENT-1-PROJECT_LOC/Core/Src/main.c + + + Application/Core/stm32wlxx_hal_msp.c + 1 + PARENT-1-PROJECT_LOC/Core/Src/stm32wlxx_hal_msp.c + + + Application/Core/stm32wlxx_it.c + 1 + PARENT-1-PROJECT_LOC/Core/Src/stm32wlxx_it.c + + + Drivers/CMSIS/system_stm32wlxx.c + 1 + PARENT-6-PROJECT_LOC/Drivers/CMSIS/Device/ST/STM32WLxx/Source/Templates/system_stm32wlxx.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cortex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_exti.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gpio.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_iwdg.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_spi.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_spi_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_tim.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_tim_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + Drivers/STM32WLxx_LL_Driver/stm32wlxx_ll_utils.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_ll_utils.c + + + Middlewares/STM32_Key_Management_Services/se_interface_kms.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Key_Management_Services/iKMS/se_interface_kms.c + + + Middlewares/STM32_Secure_Engine/se_interface_application.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_application.c + + + Middlewares/STM32_Secure_Engine/se_interface_bootloader.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_bootloader.c + + + Middlewares/STM32_Secure_Engine/se_interface_common.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_common.c + + + Application/BFU/App/sfu_boot.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_boot.c + + + Application/BFU/App/sfu_com_loader.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_com_loader.c + + + Application/BFU/App/sfu_com_trace.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_com_trace.c + + + Application/BFU/App/sfu_error.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_error.c + + + Application/BFU/App/sfu_fwimg_common.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_fwimg_common.c + + + Application/BFU/App/sfu_interface_crypto_scheme.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_interface_crypto_scheme.c + + + Application/BFU/App/sfu_kms.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_kms.c + + + Application/BFU/App/sfu_loader.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_loader.c + + + Application/BFU/App/sfu_new_image.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_new_image.c + + + Application/BFU/App/sfu_test.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_test.c + + + Application/BFU/Target/sfu_low_level.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level.c + + + Application/BFU/Target/sfu_low_level_flash.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash.c + + + Application/BFU/Target/sfu_low_level_flash_ext.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash_ext.c + + + Application/BFU/Target/sfu_low_level_flash_int.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash_int.c + + + Application/BFU/Target/sfu_low_level_security.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_security.c + + + Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + 1 + PARENT-6-PROJECT_LOC/Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/Application/Core/sfu_secorebin_inc.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Core/sfu_secorebin_inc.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/Application/Core/sfu_secorebin_inc.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Core/sfu_secorebin_inc.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/Application/Core/syscalls.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Core/syscalls.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/Application/Core/syscalls.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Core/syscalls.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/Application/Core/sysmem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Core/sysmem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/Application/Core/sysmem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Core/sysmem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_AT_Slave/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_AT_Slave/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/BFU.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/BFU.ld similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_BFU/STM32CubeIDE/BFU.ld rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/BFU.ld diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/se_interface.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/se_interface.txt new file mode 100644 index 00000000..05aa5e0b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/STM32CubeIDE/se_interface.txt @@ -0,0 +1,40 @@ +SE_APP_GetActiveFwInfo +SE_APP_SVC_Handler +SE_SYS_SaveDisableIrq +SE_SYS_RestoreEnableIrq +SE_KMS_Initialize +SE_KMS_Finalize +SE_KMS_GetInfo +SE_KMS_GetFunctionList +SE_KMS_GetSlotList +SE_KMS_GetSlotInfo +SE_KMS_GetTokenInfo +SE_KMS_GetMechanismInfo +SE_KMS_OpenSession +SE_KMS_CloseSession +SE_KMS_CreateObject +SE_KMS_DestroyObject +SE_KMS_GetAttributeValue +SE_KMS_SetAttributeValue +SE_KMS_FindObjectsInit +SE_KMS_FindObjects +SE_KMS_FindObjectsFinal +SE_KMS_EncryptInit +SE_KMS_Encrypt +SE_KMS_EncryptUpdate +SE_KMS_EncryptFinal +SE_KMS_DecryptInit +SE_KMS_Decrypt +SE_KMS_DecryptUpdate +SE_KMS_DecryptFinal +SE_KMS_DigestInit +SE_KMS_Digest +SE_KMS_DigestUpdate +SE_KMS_DigestFinal +SE_KMS_SignInit +SE_KMS_Sign +SE_KMS_VerifyInit +SE_KMS_Verify +SE_KMS_DeriveKey +SE_KMS_GenerateKeyPair +SE_KMS_GenerateRandom diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/readme.txt new file mode 100644 index 00000000..9961bd10 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_BFU/readme.txt @@ -0,0 +1,174 @@ +/** + @page 1_Image_BFU / Boot and Firmware Update Demo Application + + @verbatim + ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* + * @file readme.txt + * @brief This application shows Boot and Firmware Update example. + ****************************************************************************** + * + * Copyright (c) 2017 STMicroelectronics. All rights reserved. + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + @endverbatim + +@par Application Description + +The Boot (B) and Firmware Update (FU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates. +In addition, Secure Boot (Root of Trust services) checks and activates the STM32 security mechanisms (if any), and checks the +authenticity and integrity of user application code before every execution to ensure that invalid or malicious code +cannot be run. The Firmware Update application receives the encrypted firmware image, decrypts it, then checks +the authenticity and integrity of the code before installing it. + +The key management services provide cryptographic services to the user application through the pkcs11 APIs +(KEY ID based APIs). User application keys are stored and can be updated in a secure way (authenticity check, data decryption and +data integrity check). +This example handles 1 firmware image with 1 single slot in FLASH allowing to maximize the user application size. +As a consequence, some features are not available: + - download a new firmware image from the application + - resume firmware update procedure in case of power off during installation + +To be easily tailorable to 128 Kbytes footprint, SFU_DEBUG_MODE compilation switch is disabled. +As a consequence there is no print on terminal during BFU execution. + +For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" available from the +STMicroelectronics microcontroller website www.st.com. + +@par Keywords + +Security, SBSFU, MPU + +@par Directory contents + + - 1_Image_BFU/Core/Src/main.c Main application file + - 1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c HAL MSP module + - 1_Image_BFU/Core/Src/stm32wlxx_it.c STM32 interrupt handlers + - 1_Image_BFU/Core/Inc/app_hw.h Hardware definitions for application + - 1_Image_BFU/Core/Inc/main.h Header file for main.c + - 1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h HAL configuration file + - 1_Image_BFU/Core/Inc/stm32wlxx_it.h Header file for stm32wlxx_it.c + - 1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h BSP configuration file + - 1_Image_BFU/BFU/App/sfu_boot.c Secure Boot (SB): entry/exit points and state machine + - 1_Image_BFU/BFU/App/sfu_com_loader.c BFU communication module: local loader part + - 1_Image_BFU/BFU/App/sfu_com_trace.c BFU communication module: trace part + - 1_Image_BFU/BFU/App/sfu_error.c BFU errors management + - 1_Image_BFU/BFU/App/sfu_fwimg_common.c BFU image handling: common functionalities/services + - 1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c Crypto scheme implementation based on KMS API + - 1_Image_BFU/BFU/App/sfu_kms.c Key management service blob importation handling + - 1_Image_BFU/BFU/App/sfu_loader.c BFU Local Loader + - 1_Image_BFU/BFU/App/sfu_new_image.c BFU image handling: manage the new firmware image storage and installation + - 1_Image_BFU/BFU/App/sfu_test.c BFU security protection automatic test + - 1_Image_BFU/BFU/App/app_sfu.h Software configuration of BFU application + - 1_Image_BFU/BFU/App/sfu_boot.h Header file for sfu_boot.c + - 1_Image_BFU/BFU/App/sfu_com_loader.h Header file for sfu_com_loader.c + - 1_Image_BFU/BFU/App/sfu_com_trace.h Header file for sfu_com_trace.c + - 1_Image_BFU/BFU/App/sfu_def.h General definition for BFU application + - 1_Image_BFU/BFU/App/sfu_error.h Header file for sfu_error.c file + - 1_Image_BFU/BFU/App/sfu_fsm_states.h BFU FSM states definitions + - 1_Image_BFU/BFU/App/sfu_fwimg_internal.h Internal definitions for firmware image handling (sfu_fwimg_core.c and sfu_fwimg_services.c) + - 1_Image_BFU/BFU/App/sfu_fwimg_regions.h FLASH regions definitions for image handling + - 1_Image_BFU/BFU/App/sfu_fwimg_services.h Header file for sfu_fwimg_services.c + - 1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h Header file for sfu_interface_crypto_scheme.h + - 1_Image_BFU/BFU/App/sfu_kms.h Header file for sfu_kms.c + - 1_Image_BFU/BFU/App/sfu_loader.h Header file for sfu_loader.c + - 1_Image_BFU/BFU/App/sfu_new_image.h Header file for sfu_new_image.c + - 1_Image_BFU/BFU/App/sfu_test.h Header file for sfu_test.c + - 1_Image_BFU/BFU/App/sfu_trace.h Header file for sfu_trace.c + - 1_Image_BFU/BFU/Target/sfu_low_level.c BFU general low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash.c BFU flash low level interface (wrapper) + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c BFU internal flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c BFU external flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_security.c BFU security low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level.h Header file for general low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash.h Header file for flash low level interface (wrapper) + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h Header file for internal flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h Header file for external flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_security.h Header file for security low level interface + +@par Hardware and Software environment + + - This example runs on STM32WL55xx devices. + - This example has been tested with NUCLEO-WL55JC RevC board and can be easily tailored to any other supported device and + development board. + - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware is a feature provided by + STM32Cube programmer available on www.st.com. + - This example is linked with SE_Core binary generated by Secure Engine Core binary generation project. + - This example needs a terminal emulator. + - By default, SBSFU is configured in development mode. To switch in production mode, refer to AN5056 "Integration + guide - software expansion for STM32Cube" available from the STMicroelectronics microcontroller website + www.st.com. + - Microsoft Windows has a limitation whereby paths to files and directories cannot be longer than 256 characters. + Paths to files exceeding that limits cause tools (e.g. compilers, shell scripts) to fail reading from or writing + to such files. + As a workaround, it is advised to use the subst.exe command from within a command prompt to set up a local drive + out of an existing directory on the hard drive, such as: + C:\> subst X: \Firmware + +@par How to use it ? + +Several steps to run BFU application : + +1. Compile projects in the following order. This is mandatory as each project requests some objects generated by the + compilation of the previous one: + - 1_Image_SECoreBin (see also SECoreBin/readme.txt) + - 1_Image_BFU + - 1_Image_UserApp (see also UserApp/readme.txt) + +2. Before loading BFU image into the target, please ensure with STM32CubeProgrammer available on www.st.com that the + following are valid for the device: + - RDP Level 0 + - Write Protection disabled on all FLASH pages + - Chip has been erased + +3. Use a terminal emulator (Tera Term for example, open source free software terminal emulator that can be downloaded + from https://osdn.net/projects/ttssh2/) for UART connection with the board. + Support of YMODEM protocol is required. Serial port configuration should be : + - Baud rate = 115200 + - Data = 8 bits + - Parity = none + - Stop = 1 bit + - Flow control = none + +4. Load BFU image into target memory with your preferred toolchain or STM32CubeProgammer. + +5. Once the BFU software is downloaded, power cycle the board (unplug/plug USB cable) : the BFU + application starts and configures the security mechanisms if some of them are enabled. + +6. [If RDP is enabled] Power cycle the board a second time (unplug/plug the USB cable): the BFU application starts with + the configured securities turned on and the Tera Term connection is possible. + Caution: Make sure to use an up-to-date version of ST-LINK firmware else BFU may not start. + +7. At startup (Power On or Reset button pushed) : + - Green LED blinks every 3 seconds when a local download is waited. + - Green LED blinks every 250 ms in case of error in option bytes configuration. + - 'C' is displayed when BFU is ready for a firmware image download. To be easily tailorable to 128 Kbytes footprint, + SFU_DEBUG_MODE compilation switch is disabled. As a consequence there is no print on terminal during BFU + execution. + +8. Send the user encrypted firmware file (\1_Image\1_Image_UserApp\Binary\UserApp.sfb) with Tera Term by using menu + "File > Transfer > YMODEM > Send..." + +Note1 : Press User push-button (B1) at reset to force a local download if an application is already installed. +Note2 : The following steps enable the protections disabled by default: + - Comment "SECBOOT_DISABLE_SECURITY_IPS" in app_sfu.h. This will enable RDP, WRP, DAP, DMA, IWDG protections + as well as attack surface reduction with MPU. + - As TAMPER detection can be very sensitive, the protection remains disabled by default. + Uncomment "SFU_TAMPER_PROTECT_ENABLE" in app_sfu.h to enable it. + - In Linker_Common, update the mapping by: + - Renaming "mapping_fwimg.icf" to "mapping_fwimg_no_sec.icf". + - Renaming "mapping_sbsfu.icf" to "mapping_sbsfu_no_sec.icf". + - Renaming "mapping_fwimg_sec.icf" to "mapping_fwimg.icf". + - Renaming "mapping_sbsfu_sec.icf" to "mapping_sbsfu.icf". + These features achieve an attack surface reduction but will not make it possible to protect secrets. +Note3 : for Linux users Minicom can be used but to do so you need to compile the BFU project with the MINICOM_YMODEM + switch enabled (app_sfu.h) + + *

      © COPYRIGHT STMicroelectronics

      + */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Binary/ECCKEY.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Binary/ECCKEY.txt similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Binary/ECCKEY.txt rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Binary/ECCKEY.txt diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Binary/iv.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Binary/iv.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Binary/iv.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Binary/iv.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/Project.ewd similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/Project.ewd rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/Project.ewd diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/Project.ewp new file mode 100644 index 00000000..e381814c --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/Project.ewp @@ -0,0 +1,1054 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_KMS_Blob + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + cmd /C "cmd /C $PROJ_DIR$\postbuild.bat "$PROJ_DIR$" "KMS_Blob" 1 " + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + User + + $PROJ_DIR$\..\Src\kms_blob_example_keys.c + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/postbuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/postbuild.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/postbuild.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/postbuild.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/stm32wl55xx_flash_cm4.icf similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/EWARM/stm32wl55xx_flash_cm4.icf rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/EWARM/stm32wl55xx_flash_cm4.icf diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/KMS_Blob.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/KMS_Blob.sct similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/KMS_Blob.sct rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/KMS_Blob.sct diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/KMS_blob.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/KMS_blob.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/KMS_blob.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/KMS_blob.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/Project.uvoptx similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/Project.uvoptx rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/Project.uvoptx diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..f5c7e0c9 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx @@ -0,0 +1,422 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_KMS_Blob + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + KMS_blob + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 1 + fromelf #L --bin --output=$L../../@L.bin + postbuild.bat . @L 1 + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4 + + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../1_Image_SECoreBin/Inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 0 + 0 + + + + KMS_Blob.sct + + + --diag_suppress L6305W + + + + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Application/User + + + kms_blob_example_keys.c + 1 + ../Src/kms_blob_example_keys.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/postbuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/postbuild.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/MDK-ARM/postbuild.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/MDK-ARM/postbuild.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/STM32CubeIDE/.cproject new file mode 100644 index 00000000..447ffaf6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/STM32CubeIDE/.cproject @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/STM32CubeIDE/.project similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/.project rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/STM32CubeIDE/.project diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/KMS_Blob.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/STM32CubeIDE/KMS_Blob.ld similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/STM32CubeIDE/KMS_Blob.ld rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/STM32CubeIDE/KMS_Blob.ld diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Src/kms_blob_example_keys.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Src/kms_blob_example_keys.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/Src/kms_blob_example_keys.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/Src/kms_blob_example_keys.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/readme.txt similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_KMS_Blob/readme.txt rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_KMS_Blob/readme.txt diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/ECCKEY1.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/ECCKEY1.txt similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/ECCKEY1.txt rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/ECCKEY1.txt diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/nonce.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/nonce.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Binary/nonce.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Binary/nonce.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/Project.ewd similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/Project.ewd rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/Project.ewd diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/Project.ewp new file mode 100644 index 00000000..37823294 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/Project.ewp @@ -0,0 +1,1181 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_SECoreBin + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + cmd /C "cmd /C $PROJ_DIR$\prebuild.bat "$PROJ_DIR$" " + + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + User + + $PROJ_DIR$\..\Src\se_low_level.c + + + $PROJ_DIR$\..\Src\kms_low_level.c + + + $PROJ_DIR$\..\Src\nvms_low_level.c + + + $PROJ_DIR$\..\Src\ca_low_level.c + + + + + Drivers + + STM32WLxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cryp.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cryp_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pka.c + + + + + Middlewares + + STM32_Secure_Engine + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_callgate.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_exception.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_fwimg.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_startup.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_user_application.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_utils.c + + + + STM32_Key_Management_Services + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_der_x962.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_ecc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_entry.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_init.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_mem.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_objects.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_platf_objects.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_digest.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_dyn_obj.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_enc_dec.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_key_mgt.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_nvm_storage.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_sign_verify.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Interface\CryptoApi\ca_core.c + + + + Third_Party + + mbed-crypto + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\Third_Party\mbed-crypto\library\sha256.c + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat new file mode 100644 index 00000000..1613be66 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat @@ -0,0 +1,123 @@ +::Post build for SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files (x86)\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfu=%userAppBinary%\\%execname%.sfu" +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" + + +set "nonce=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\nonce.bin" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\Project.out" +set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_GCM.bin" +set "magic=SFU%fwid%" +set "offset=512" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +set "command=%python%%prepareimage% enc -k %oemkey% -n %nonce% %bin% %sfu% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sign -k %oemkey% -n %nonce% %bin% %sign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% %sfb% -o %offset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% -o %offset% %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat new file mode 100644 index 00000000..410c0cd7 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat @@ -0,0 +1,119 @@ +::Post build for SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files (x86)\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" + +set "oemkey=" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\Project.out" +set "magic=SFU%fwid%" +set "offset=512" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" > %projectdir%\output.txt 2>&1 +IF %ERRORLEVEL% NEQ 0 goto :error +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +:: no encryption +set "command=%python%%prepareimage% sha256 %bin% %sign% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:: no encryption so pack the binary file +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% %sfb% -o %offset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% -o %offset% %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat new file mode 100644 index 00000000..70c88811 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat @@ -0,0 +1,122 @@ +::Post build for SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files (x86)\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfu=%userAppBinary%\\%execname%.sfu" +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" + +set "iv=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\iv.bin" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\Project.out" +set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_CBC.bin" +set "magic=SFU%fwid%" +set "offset=512" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +set "command=%python%%prepareimage% enc -k %oemkey% -i %iv% %bin% %sfu% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sha256 %bin% %sign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% %sfb% -o %offset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% -o %offset% %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/prebuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/prebuild.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/EWARM/prebuild.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/prebuild.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf new file mode 100644 index 00000000..3faa0f34 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf @@ -0,0 +1,24 @@ +/*###ICF### Set of symbols used in SE and SB_SFU projects ****/ + +define memory mem with size = 4G; + +/******************************************************************************/ +/* Include of SE symbols file */ +/* (Project>Options>Linker>Extra Options --config_search option is used to */ +/* specify the the directory to search for include files */ +/******************************************************************************/ +include "mapping_sbsfu.icf"; +include "mapping_fwimg.icf"; + +initialize by copy { readwrite }; +do not initialize { section .noinit}; + +/******************************************************************************/ +/* placement instructions */ +/******************************************************************************/ +place at address mem:__ICFEDIT_SE_CallGate_region_ROM_start__ { readonly section .SE_CallGate_Code }; +place at address mem:__ICFEDIT_SE_Startup_region_ROM_start__ { readonly section .SE_Startup_Code}; +place in SE_CODE_NOKEY_ROM_region {readonly}; +place in SE_Key_ROM_region { readonly section .SE_embedded_Keys }; +keep { section .SE_embedded_Keys }; +place in SE_RAM_region {readwrite}; diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/ca_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/ca_conf.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/ca_conf.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/ca_conf.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/ca_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/ca_low_level.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/ca_low_level.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/ca_low_level.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_config.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_config.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_config.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_config.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_low_level.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_low_level.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_low_level.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_mem_pool_def.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_mem_pool_def.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_mem_pool_def.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_mem_pool_def.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_platf_objects_interface.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_platf_objects_interface.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/kms_platf_objects_interface.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/kms_platf_objects_interface.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/mbed_crypto_config.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/mbed_crypto_config.h new file mode 100644 index 00000000..5ea26e4f --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/mbed_crypto_config.h @@ -0,0 +1,1976 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +/* + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CONFIG_H +#define MBEDTLS_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/aria.c + * library/timing.c + * include/mbedtls/bn_mul.h + * + * Required by: + * MBEDTLS_AESNI_C + * MBEDTLS_PADLOCK_C + * + * Comment to disable the use of assembly code. + */ +//#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +//#define MBEDTLS_NO_UDBL_DIVISION + +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +//#define MBEDTLS_NO_64BIT_MULTIPLICATION + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions + */ +//#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). + * The time needs to be correct (not necessarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. + */ +//#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT +//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions so that they generate a warning if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions so that they generate an error if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * Uncomment to get errors on using deprecated functions. + */ +#define MBEDTLS_DEPRECATED_REMOVED + +/** + * \def MBEDTLS_CHECK_PARAMS + * + * This configuration option controls whether the library validates more of + * the parameters passed to it. + * + * When this flag is not defined, the library only attempts to validate an + * input parameter if: (1) they may come from the outside world (such as the + * network, the filesystem, etc.) or (2) not validating them could result in + * internal memory errors such as overflowing a buffer controlled by the + * library. On the other hand, it doesn't attempt to validate parameters whose + * values are fully controlled by the application (such as pointers). + * + * When this flag is defined, the library additionally attempts to validate + * parameters that are fully controlled by the application, and should always + * be valid if the application code is fully correct and trusted. + * + * For example, when a function accepts as input a pointer to a buffer that may + * contain untrusted data, and its documentation mentions that this pointer + * must not be NULL: + * - the pointer is checked to be non-NULL only if this option is enabled + * - the content of the buffer is always validated + * + * When this flag is defined, if a library function receives a parameter that + * is invalid, it will: + * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a + * call to the function mbedtls_param_failed() + * - immediately return (with a specific error code unless the function + * returns void and can't communicate an error). + * + * When defining this flag, you also need to: + * - either provide a definition of the function mbedtls_param_failed() in + * your application (see platform_util.h for its prototype) as the library + * calls that function, but does not provide a default definition for it, + * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED() + * below if the above mechanism is not flexible enough to suit your needs. + * See the documentation of this macro later in this file. + * + * Uncomment to enable validation of application-controlled parameters. + */ +//#define MBEDTLS_CHECK_PARAMS + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + * + * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_ARIA_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT +//#define MBEDTLS_CMAC_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT +//#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT +//#define MBEDTLS_XTEA_ALT + +/* + * When replacing the elliptic curve module, pleace consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT + +/** + * \def MBEDTLS_MD2_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * \note Because of a signature change, the core AES encryption and decryption routines are + * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, + * respectively. When setting up alternative implementations, these functions should + * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * must stay untouched. + * + * \note If you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + * + * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use + * constitutes a security risk. If possible, we recommend avoiding + * dependencies on them, and considering stronger message digests + * and ciphers instead. + * + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT +//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT +//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT +//#define MBEDTLS_ECDSA_VERIFY_ALT +//#define MBEDTLS_ECDSA_SIGN_ALT +//#define MBEDTLS_ECDSA_GENKEY_ALT + +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac + * function, but will use your mbedtls_internal_ecp_double_jac if the group is + * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when + * receives it as an argument). If the group is not supported then the original + * implementation is used. The other functions and the definition of + * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your + * implementation of mbedtls_internal_ecp_double_jac and + * mbedtls_internal_ecp_grp_capable must be compatible with this definition. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +//#define MBEDTLS_TEST_NULL_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Use precomputed AES tables stored in ROM. + * + * Uncomment this macro to use precomputed AES tables stored in ROM. + * Comment this macro to generate AES tables in RAM at runtime. + * + * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb + * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the + * initialization time before the first AES operation can be performed. + * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c + * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded + * performance if ROM access is slower than RAM access. + * + * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + * + */ +//#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_AES_FEWER_TABLES + * + * Use less ROM/RAM for AES tables. + * + * Uncommenting this macro omits 75% of the AES tables from + * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) + * by computing their values on the fly during operations + * (the tables are entry-wise rotations of one another). + * + * Tradeoff: Uncommenting this reduces the RAM / ROM footprint + * by ~6kb but at the cost of more arithmetic operations during + * runtime. Specifically, one has to compare 4 accesses within + * different tables to 4 accesses with additional arithmetic + * operations within the same table. The performance gain/loss + * depends on the system and memory details. + * + * This option is independent of \c MBEDTLS_AES_ROM_TABLES. + * + */ +//#define MBEDTLS_AES_FEWER_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +//#define MBEDTLS_CIPHER_MODE_XTS + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * This module is required to support the TLS ciphersuites that use the NULL + * cipher. + * + * Uncomment this macro to enable the NULL cipher + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +//#define MBEDTLS_CIPHER_PADDING_PKCS7 +//#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +//#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +//#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +//#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +//#define MBEDTLS_ECP_DP_BP256R1_ENABLED +//#define MBEDTLS_ECP_DP_BP384R1_ENABLED +//#define MBEDTLS_ECP_DP_BP512R1_ENABLED +//#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +//#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +//#define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECP_RESTARTABLE + * + * Enable "non-blocking" ECC operations that can return early and be resumed. + * + * This allows various functions to pause by returning + * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in Mbed TLS's SSL module, + * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in order + * to further progress and eventually complete their operation. This is + * controlled through mbedtls_ecp_set_max_ops() which limits the maximum number + * of ECC operations a function may perform before pausing; see + * mbedtls_ecp_set_max_ops() for more information. + * + * This is useful in non-threaded environments if you want to avoid blocking + * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. + * + * Uncomment this macro to enable restartable ECC computations. + * + * \note This option only works with the default software implementation of + * elliptic curve functionality. It is incompatible with + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. + */ +//#define MBEDTLS_ECP_RESTARTABLE + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +//#define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +//#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +//#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +//#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + * + * In PSA key storage, encode the owner of the key. + * + * This is only meaningful when building the library as part of a + * multi-client service. When you activate this option, you must provide + * an implementation of the type psa_key_owner_id_t and a translation + * from psa_key_file_id_t to file name in all the storage backends that + * you wish to support. + * + * Note that this option is meant for internal use only and may be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +//#define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +//#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +//#define MBEDTLS_PKCS1_V21 + +/** + * \def MBEDTLS_PSA_CRYPTO_SPM + * + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure + * Partition Manager) integration which separates the code into two parts: a + * NSPE (Non-Secure Process Environment) and an SPE (Secure Process + * Environment). + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SPM + +/** + * \def MBEDTLS_PSA_INJECT_ENTROPY + * + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. + * + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED + * + */ +//#define MBEDTLS_PSA_INJECT_ENTROPY + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_USE_PSA_CRYPTO + * + * Make the X.509 and TLS library use PSA for cryptographic operations, see + * #MBEDTLS_PSA_CRYPTO_C. + * + * Note: this option is still in progress, the full X.509 and TLS modules are + * not covered yet, but parts that are not ported to PSA yet will still work + * as usual, so enabling this option should not break backwards compatibility. + * + * \warning Support for PSA is still an experimental feature. + * Any public API that depends on this option may change + * at any time until this warning is removed. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + */ +//#define MBEDTLS_USE_PSA_CRYPTO + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +//#define MBEDTLS_VERSION_FEATURES + +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/cipher.c + * library/pem.c + * library/ctr_drbg.c + * + * This module is required to support the TLS ciphersuites that use the AES + * cipher. + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +//#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the ARC4 + * cipher. + * + * \warning ARC4 is considered a weak cipher and its use constitutes a + * security risk. If possible, we recommend avoidng dependencies on + * it, and considering stronger ciphers instead. + * + */ +//#define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +//#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + */ +//#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +//#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/rsa_internal.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +//#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +//#define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * Camellia cipher. + */ +//#define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_ARIA_C + * + * Enable the ARIA block cipher. + * + * Module: library/aria.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * ARIA cipher. + */ +//#define MBEDTLS_ARIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support AES-CCM ciphersuites in TLS. + */ +//#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +//#define MBEDTLS_CHACHA20_C + +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +//#define MBEDTLS_CHACHAPOLY_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * + * Uncomment to enable generic cipher wrappers. + */ +//#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +//#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-based random generator. + * The CTR_DRBG generator uses AES-256 by default. + * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES random number generator. + */ +//#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the DES + * cipher. + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + * + * \warning DES is considered a weak cipher and its use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +//#define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +//#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + */ +//#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +//#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +//#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +//#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support the TLS ciphersuites that use GCM. + */ +//#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +//#define MBEDTLS_HKDF_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +//#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_NIST_KW_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +//#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + * + * \warning MD2 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + * + * \warning MD4 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * + * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 + * depending on the handshake parameters. Further, it is used for checking + * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded + * encrypted keys. + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * + * This modules translates between OIDs and internal values. + */ +//#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +//#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +//#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymmetric) key layer. + * + * Module: library/pk.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +//#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymmetric) key parser. + * + * Module: library/pkparse.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +//#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymmetric) key writer. + * + * Module: library/pkwrite.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +//#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +//#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +//#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +//#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +//#define MBEDTLS_POLY1305_C + +/** + * \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * Module: library/psa_crypto.c + * + * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_C + +/** + * \def MBEDTLS_PSA_CRYPTO_STORAGE_C + * + * Enable the Platform Security Architecture persistent key storage. + * + * Module: library/psa_crypto_storage.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface + */ +//#define MBEDTLS_PSA_CRYPTO_STORAGE_C + +/** + * \def MBEDTLS_PSA_ITS_FILE_C + * + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. + * + * Module: library/psa_its_file.c + * + * Requires: MBEDTLS_FS_IO + */ +//#define MBEDTLS_PSA_ITS_FILE_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +//#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * library/rsa_internal.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +/* #define MBEDTLS_RSA_C */ + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * + * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 + * depending on the handshake parameters, and for SHA1-signed certificates. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-384 and SHA-512. + */ +//#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by Mbed + * TLS's \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and + * provide your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +//#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +//#define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ + +/** + * Uncomment the macro to let mbed TLS use your alternate implementation of + * mbedtls_platform_zeroize(). This replaces the default implementation in + * platform_util.c. + * + * mbedtls_platform_zeroize() is a widely used function across the library to + * zero a block of memory. The implementation is expected to be secure in the + * sense that it has been written to prevent the compiler from removing calls + * to mbedtls_platform_zeroize() as part of redundant code elimination + * optimizations. However, it is difficult to guarantee that calls to + * mbedtls_platform_zeroize() will not be optimized by the compiler as older + * versions of the C language standards do not provide a secure implementation + * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to + * configure their own implementation of mbedtls_platform_zeroize(), for + * example by using directives specific to their compiler, features from newer + * C standards (e.g using memset_s() in C11) or calling a secure memset() from + * their system (e.g explicit_bzero() in BSD). + */ +//#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + +/* \} name SECTION: Customisation configuration options */ + +/* Target and application specific configurations + * + * Allow user to override any previous default. + * + */ +#if defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +#include "mbedtls/check_config.h" + +#endif /* MBEDTLS_CONFIG_H */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/nvms_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/nvms_low_level.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/nvms_low_level.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/nvms_low_level.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/se_crypto_config.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/se_crypto_config.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/se_crypto_config.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/se_crypto_config.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/se_def_metadata.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/se_def_metadata.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/se_def_metadata.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/se_def_metadata.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/se_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/se_low_level.h new file mode 100644 index 00000000..bd8b79e1 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/se_low_level.h @@ -0,0 +1,184 @@ +/** + ****************************************************************************** + * @file se_low_level.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Engine low level interface + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SE_LOW_LEVEL_H +#define SE_LOW_LEVEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "se_def.h" + +/* Secure Engine needs to know the slots configuration for the Read/Write services in protected area + (see @ref SE_IMG_Write, see @ref SE_IMG_Read) */ +#include "sfu_fwimg_regions.h" + +#include "stm32wlxx_hal.h" + +/** @addtogroup SE + * @{ + */ + +/** @addtogroup SE_HARDWARE + * @{ + */ + +/** @defgroup SE_HARDWARE_Exported_Constants Exported Constants + * @{ + */ +/** + * @brief flash handling constants: these constants are used in se_fwimg.c + */ + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Macros Exported Macros + * @{ + */ + +/** @defgroup SE_HARDWARE_Exported_Macros_CRC CRC Settings + * @{ + */ + +/** + * @brief Set CRC 32 of the BootInfoTypeDef pointer passed as parameter + * The CRC is computed with the structure without its CRC field and the length is provided to SE_CRC_Calculate in + * 32-bit word. + * Please note that this works only if the CRC field is kept as the last uint32_t of the SE_BootInfoTypeDef structure. + */ +#define SE_BOOT_CONFIG_SET_CRC_32(x) \ + do{ \ + (x)->CRC32 = SE_CRC_Calculate ((uint32_t*)(x), (sizeof(SE_BootInfoTypeDef)-sizeof(uint32_t))/sizeof(uint32_t));\ + }while(0) + +/** + * @brief Set CRC of the BootInfoTypeDef pointer passed as parameter + */ +#define SE_BOOT_CONFIG_SET_CRC(x) SE_BOOT_CONFIG_SET_CRC_32(x) + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Macros_CodeIsolation Code Isolation Settings + * @brief These settings configure the way the Secure Engine is isolated from the rest of the code. + * @{ + */ + +/** + * MPU : Enter/Exit secured area ==> nothing to do + */ +#define ENTER_PROTECTED_AREA() do { /* do nothing */; } while(0) +#define EXIT_PROTECTED_AREA() do { /* do nothing */; } while(0) + +/** @addtogroup SE_LOW_LEVEL_Exported_Functions + * @{ + */ +void SE_LL_CORE_Cleanup(void); + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Exported_Functions + * @{ + */ + +/** @addtogroup SE_HARDWARE_Exported_CRC_Functions + * @{ + */ +SE_ErrorStatus SE_LL_CRC_Config(void); +SE_ErrorStatus SE_LL_CRC_Init(void); +SE_ErrorStatus SE_LL_CRC_DeInit(void); +uint32_t SE_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t uBufferLength); + +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Exported_FLASH_Functions + * @{ + */ +SE_ErrorStatus SE_LL_FLASH_Erase(uint8_t *pStart, uint32_t Length); +SE_ErrorStatus SE_LL_FLASH_Write(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SE_ErrorStatus SE_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); + +void NMI_Handler(void); +void HardFault_Handler(void); +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Exported_FLASH_EXT_Functions + * @{ + */ +SE_ErrorStatus SE_LL_FLASH_EXT_Decrypt_Init(SE_FwRawHeaderTypeDef *pxSE_Metadata); +/** + * @} + */ + +/** @addtogroup SE_BUFFER_CHECK_Exported_RAM_Functions + * @{ + */ + +SE_ErrorStatus SE_LL_Buffer_in_ram(void *pBuff, uint32_t Length); +SE_ErrorStatus SE_LL_Buffer_in_SBSFU_ram(const void *pBuff, uint32_t Length); +SE_ErrorStatus SE_LL_Buffer_part_of_SE_ram(const void *pBuff, uint32_t Length); +SE_ErrorStatus SE_LL_Buffer_part_of_SE_rom(const void *pBuff, uint32_t Length); +/** + * @} + */ + +/** @addtogroup SE_LOCK_KEYS_Exported_Functions + * @{ + */ +SE_ErrorStatus SE_LL_Lock_Keys(void); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SE_LOW_LEVEL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/Project.uvoptx new file mode 100644 index 00000000..790df77b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/Project.uvoptx @@ -0,0 +1,701 @@ + + + + 1.0 + +
      ### uVision Project, (C) Keil Software
      + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32WL55JC_Nucleo_1_Image_SECoreBin + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + ST-LINKIII-KEIL_SWO + -U001F00313038511234333935 -O206 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4.FLM -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + + + + 1 + 0 + 0x20005AF8 + 0 + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\data_init.c + data_init.c + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ../Src/ca_low_level.c + ca_low_level.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ../Src/kms_low_level.c + kms_low_level.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ../Src/nvms_low_level.c + nvms_low_level.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ../Src/se_low_level.c + se_low_level.c + 0 + 0 + + + + + Doc + 1 + 0 + 0 + 0 + + 3 + 6 + 5 + 0 + 0 + 0 + ../readme.txt + readme.txt + 0 + 0 + + + + + Drivers/STM32WLxx_HAL_Driver + 0 + 0 + 0 + 0 + + 4 + 7 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + stm32wlxx_hal_crc.c + 0 + 0 + + + 4 + 8 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + stm32wlxx_hal_crc_ex.c + 0 + 0 + + + 4 + 9 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c + stm32wlxx_hal_cryp.c + 0 + 0 + + + 4 + 10 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c + stm32wlxx_hal_cryp_ex.c + 0 + 0 + + + 4 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_dma.c + stm32wlxx_hal_dma.c + 0 + 0 + + + 4 + 12 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + stm32wlxx_hal_flash.c + 0 + 0 + + + 4 + 13 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + stm32wlxx_hal_flash_ex.c + 0 + 0 + + + 4 + 14 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c + stm32wlxx_hal_pka.c + 0 + 0 + + + + + Middlewares/STM32_Secure_Engine + 0 + 0 + 0 + 0 + + 5 + 15 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c + se_callgate.c + 0 + 0 + + + 5 + 16 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c + se_exception.c + 0 + 0 + + + 5 + 17 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c + se_fwimg.c + 0 + 0 + + + 5 + 18 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c + se_startup.c + 0 + 0 + + + 5 + 19 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c + se_user_application.c + 0 + 0 + + + 5 + 20 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c + se_utils.c + 0 + 0 + + + + + Middlewares/STM32_Key_Management_Services + 0 + 0 + 0 + 0 + + 6 + 21 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c + ca_core.c + 0 + 0 + + + 6 + 22 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c + kms_der_x962.c + 0 + 0 + + + 6 + 23 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c + kms_digest.c + 0 + 0 + + + 6 + 24 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c + kms_dyn_obj.c + 0 + 0 + + + 6 + 25 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c + kms_ecc.c + 0 + 0 + + + 6 + 26 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c + kms_enc_dec.c + 0 + 0 + + + 6 + 27 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c + kms_entry.c + 0 + 0 + + + 6 + 28 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c + kms_init.c + 0 + 0 + + + 6 + 29 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c + kms_key_mgt.c + 0 + 0 + + + 6 + 30 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c + kms_mem.c + 0 + 0 + + + 6 + 31 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c + kms_nvm_storage.c + 0 + 0 + + + 6 + 32 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c + kms_objects.c + 0 + 0 + + + 6 + 33 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c + kms_platf_objects.c + 0 + 0 + + + 6 + 34 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c + kms_sign_verify.c + 0 + 0 + + + + + Middlewares/Third_Party/mbed-crypto + 0 + 0 + 0 + 0 + + 7 + 35 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/platform_util.c + platform_util.c + 0 + 0 + + + 7 + 36 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/sha256.c + sha256.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..46bcfce1 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/Project.uvprojx @@ -0,0 +1,619 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_SECoreBin + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + SECoreBin + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 1 + + prebuild.bat . + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf #L --bin --output=$L@L.bin + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED,MBEDTLS_CONFIG_FILE=<mbed_crypto_config.h>,IT_MANAGEMENT_DISABLED + + .;../Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../../../../../Middlewares/ST/STM32_Secure_Engine/Key;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules;../../../../../../Middlewares/Third_Party/mbed-crypto/include;../../1_Image_BFU/BFU/App;../../1_Image_BFU/BFU/Target;../../Linker_Common/MDK-ARM + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + SECoreBin.sct + + + --entry=SE_CallGate +--diag_suppress L6404W +--diag_suppress L6314W + + + + + + + + Application/MDK-ARM + + + data_init.c + 1 + .\data_init.c + + + + + Application/User + + + ca_low_level.c + 1 + ../Src/ca_low_level.c + + + kms_low_level.c + 1 + ../Src/kms_low_level.c + + + nvms_low_level.c + 1 + ../Src/nvms_low_level.c + + + se_low_level.c + 1 + ../Src/se_low_level.c + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Drivers/STM32WLxx_HAL_Driver + + + stm32wlxx_hal_crc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + stm32wlxx_hal_crc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + stm32wlxx_hal_cryp.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c + + + stm32wlxx_hal_cryp_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c + + + stm32wlxx_hal_dma.c + 1 + ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_dma.c + + + stm32wlxx_hal_flash.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + stm32wlxx_hal_flash_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + stm32wlxx_hal_pka.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c + + + + + Middlewares/STM32_Secure_Engine + + + se_callgate.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c + + + se_exception.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c + + + se_fwimg.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c + + + se_startup.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c + + + se_user_application.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c + + + se_utils.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c + + + + + Middlewares/STM32_Key_Management_Services + + + ca_core.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c + + + kms_der_x962.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c + + + kms_digest.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c + + + kms_dyn_obj.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c + + + kms_ecc.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c + + + kms_enc_dec.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c + + + kms_entry.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c + + + kms_init.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c + + + kms_key_mgt.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c + + + kms_mem.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c + + + kms_nvm_storage.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c + + + kms_objects.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c + + + kms_platf_objects.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c + + + kms_sign_verify.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c + + + + + Middlewares/Third_Party/mbed-crypto + + + platform_util.c + 1 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/platform_util.c + + + sha256.c + 1 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/sha256.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct new file mode 100644 index 00000000..a5aba32a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct @@ -0,0 +1,26 @@ +#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0plus -E -xc +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* +#include "..\..\Linker_Common\MDK-ARM\mapping_sbsfu.h" +#include "..\..\Linker_Common\MDK-ARM\mapping_fwimg.h" + + +; *** regions needed by SE_CoreBin project *** +LR_SE SE_CODE_REGION_ROM_START { + SE_CallGate_region_ROM SE_CALLGATE_REGION_ROM_START FIXED SE_CALLGATE_REGION_ROM_SIZE { + *(.SE_CallGate_Code) + } + SE_Key_region_ROM SE_KEY_REGION_ROM_START FIXED SE_KEY_REGION_ROM_SIZE { + *(.SE_embedded_Keys) + } + SE_Startup_region_ROM SE_STARTUP_REGION_ROM_START FIXED { + *(.SE_Startup_Code) + } + SE_Code_NoKey_region SE_CODE_NOKEY_REGION_ROM_START FIXED SE_ROM_REGION_SIZE{ + .ANY (+RO) + } + SE_region_RAM SE_REGION_RAM_STACK_TOP SE_RAM_REGION_SIZE { + .ANY (+RW +ZI) + } +} diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/data_init.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/data_init.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/data_init.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/data_init.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/postbuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/postbuild.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/postbuild.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/postbuild.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/prebuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/prebuild.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/MDK-ARM/prebuild.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/MDK-ARM/prebuild.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/.cproject new file mode 100644 index 00000000..8c2f37a9 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/.cproject @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/.project new file mode 100644 index 00000000..e65aa4fa --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/.project @@ -0,0 +1,201 @@ + + + 1_Image_SECoreBin + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doc/readme.txt + 1 + $%7BPARENT-1-PROJECT_LOC%7D/readme.txt + + + Application/User/ca_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/ca_low_level.c + + + Application/User/kms_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/kms_low_level.c + + + Application/User/nvms_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/nvms_low_level.c + + + Application/User/se_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/se_low_level.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cryp.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cryp_ex.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pka.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c + + + Middlewares/STM32_Key_Management_Services/ca_core.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c + + + Middlewares/STM32_Key_Management_Services/kms_der_x962.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c + + + Middlewares/STM32_Key_Management_Services/kms_digest.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c + + + Middlewares/STM32_Key_Management_Services/kms_dyn_obj.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c + + + Middlewares/STM32_Key_Management_Services/kms_ecc.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c + + + Middlewares/STM32_Key_Management_Services/kms_enc_dec.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c + + + Middlewares/STM32_Key_Management_Services/kms_entry.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c + + + Middlewares/STM32_Key_Management_Services/kms_init.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c + + + Middlewares/STM32_Key_Management_Services/kms_key_mgt.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c + + + Middlewares/STM32_Key_Management_Services/kms_mem.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c + + + Middlewares/STM32_Key_Management_Services/kms_nvm_storage.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c + + + Middlewares/STM32_Key_Management_Services/kms_objects.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c + + + Middlewares/STM32_Key_Management_Services/kms_platf_objects.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c + + + Middlewares/STM32_Key_Management_Services/kms_sign_verify.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c + + + Middlewares/STM32_Secure_Engine/se_callgate.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c + + + Middlewares/STM32_Secure_Engine/se_exception.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c + + + Middlewares/STM32_Secure_Engine/se_fwimg.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c + + + Middlewares/STM32_Secure_Engine/se_startup.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c + + + Middlewares/STM32_Secure_Engine/se_user_application.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c + + + Middlewares/STM32_Secure_Engine/se_utils.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c + + + Middlewares/Third_Party/mbed-crypto/sha256.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/Third_Party/mbed-crypto/library/sha256.c + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/Application/User/syscalls.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/Application/User/syscalls.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/Application/User/syscalls.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/Application/User/syscalls.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/Application/User/sysmem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/Application/User/sysmem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/STM32CubeIDE/Application/User/sysmem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/Application/User/sysmem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld new file mode 100644 index 00000000..3cb3b060 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld @@ -0,0 +1,152 @@ +/* +** LinkerScript +*/ + +/* Entry Point */ +ENTRY(SE_CallGate) + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0; /* specific stack provided inside secured area */ + +INCLUDE mapping_fwimg.ld +INCLUDE mapping_sbsfu.ld + +/* Define output sections */ +SECTIONS +{ + .SE_CallGate_Code : + { + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + KEEP(*(.SE_CallGate_Code)) + } > SE_CallGate_ROM_region + + .SE_embedded_Keys : { KEEP(*(.SE_embedded_Keys)) } > SE_Key_region_ROM + + .SE_Startup_Code : { KEEP ( *se_startup.o (.text .text*)) } > SE_Startup_ROM_region + .text : + { + . = ALIGN(8); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(8); + _etext = .; /* define a global symbols at end of code */ + } >SE_Code_NoKey_ROM_region + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .ARM.extab : + { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + } >SE_RAM_region AT>SE_Code_NoKey_ROM_region + + + /* Uninitialized data section */ + . = ALIGN(8); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >SE_RAM_region + + /* User_heap_stack section, used to check that there is enough "SRAM1" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SE_RAM_region + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/ca_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/ca_low_level.c new file mode 100644 index 00000000..30759a90 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/ca_low_level.c @@ -0,0 +1,255 @@ +/** + ****************************************************************************** + * @file ca_low_level.c + * @author MCD Application Team + * @brief This file contains the low level implementations of the Cryptographic API (CA) module. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef CA_LOW_LEVEL_C +#define CA_LOW_LEVEL_C + +/* Includes ------------------------------------------------------------------*/ +#include "CryptoApi/ca.h" +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +#include "mbedtls/entropy_poll.h" +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ + +/* Private defines -----------------------------------------------------------*/ +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +#define COMPILER_BARRIER() __DMB();__DSB(); +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ +/* Private typedef -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +static RNG_HandleTypeDef handle; +static uint8_t users = 0; +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ +/* Private function prototypes -----------------------------------------------*/ +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +static uint8_t atomic_incr_u8(__IO uint8_t *valuePtr, uint8_t delta); +static void RNG_Init(void); +static void RNG_GetBytes(uint8_t *output, size_t length, size_t *output_length); +static void RNG_DeInit(void); +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ + +/* Exported functions implementation -----------------------------------------*/ + +#if defined(CA_HAL_CRYPTOLIB_SUPP) + +#if ((CA_ROUTE_AES_CBC & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_CCM & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_CMAC & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_ECB & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_GCM & CA_ROUTE_MASK) == CA_ROUTE_HAL) + +/** + * @brief CRYP MSP Initialization + * This function configures the hardware resources + * @param hcryp: CRYP handle pointer + * @retval None + */ +void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp) +{ + if (hcryp->Instance == CA_AES_INSTANCE) + { + /* Release AES/CRYP from reset state */ + __HAL_RCC_AES_RELEASE_RESET(); + /* Peripheral clock enable */ + __HAL_RCC_AES_CLK_ENABLE(); + } +} + +/** + * @brief CRYP MSP De-Initialization + * This function freeze the hardware resources + * @param hcryp: CRYP handle pointer + * @retval None + */ +void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp) +{ + if (hcryp->Instance == CA_AES_INSTANCE) + { + /* Peripheral clock disable */ + __HAL_RCC_AES_CLK_DISABLE(); + /* Force AES/CRYP into reset state */ + __HAL_RCC_AES_FORCE_RESET(); + } +} +#endif /* CA_ROUTE_AES_CBC || CA_ROUTE_AES_CCM || CA_ROUTE_AES_CMAC \ + || CA_ROUTE_AES_ECB || CA_ROUTE_AES_GCM => CA_ROUTE_HAL */ + + +#if ((CA_ROUTE_ECC_ECDSA & CA_ROUTE_MASK) == CA_ROUTE_HAL) || ((CA_ROUTE_RSA & CA_ROUTE_MASK) == CA_ROUTE_HAL) +/** + * @brief PKA MSP Initialization + * This function configures the hardware resources used in this example + * @param[in] hpka: PKA handle pointer + * @retval None + */ +void HAL_PKA_MspInit(PKA_HandleTypeDef *hpka) +{ + if (hpka->Instance == CA_PKA_INSTANCE) + { + /* Release PKA from reset state */ + __HAL_RCC_PKA_RELEASE_RESET(); + /* Peripheral clock enable */ + __HAL_RCC_PKA_CLK_ENABLE(); + } +} + +/** + * @brief PKA MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param[in] hpka: PKA handle pointer + * @retval None + */ +void HAL_PKA_MspDeInit(PKA_HandleTypeDef *hpka) +{ + if (hpka->Instance == CA_PKA_INSTANCE) + { + /* Peripheral clock disable */ + __HAL_RCC_PKA_CLK_DISABLE(); + /* Force PKA into reset state */ + __HAL_RCC_PKA_FORCE_RESET(); + } +} +#endif /* CA_ROUTE_ECC_ECDSA || CA_ROUTE_RSA => CA_ROUTE_HAL */ + +#endif /* CA_HAL_CRYPTOLIB_SUPP */ + +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +static uint8_t atomic_incr_u8(__IO uint8_t *valuePtr, uint8_t delta) +{ + COMPILER_BARRIER(); + uint8_t newValue; + do + { + newValue = __LDREXB(valuePtr) + delta; + } while (__STREXB(newValue, valuePtr)); + COMPILER_BARRIER(); + return newValue; +} + +static void RNG_Init(void) +{ + uint32_t dummy; + + /* We're only supporting a single user of RNG */ + if (atomic_incr_u8(&users, 1) > 1) + { + while (1); + } + + /* Select MSI as RNG clock source */ + __HAL_RCC_RNG_CONFIG(RCC_RNGCLKSOURCE_MSI); + + /* RNG Peripheral clock enable */ + __HAL_RCC_RNG_CLK_ENABLE(); + + /* Initialize RNG instance */ + handle.Instance = RNG; + handle.State = HAL_RNG_STATE_RESET; + handle.Lock = HAL_UNLOCKED; + + HAL_RNG_Init(&handle); + + /* first random number generated after setting the RNGEN bit should not be used */ + HAL_RNG_GenerateRandomNumber(&handle, &dummy); +} + +static void RNG_GetBytes(uint8_t *output, size_t length, size_t *output_length) +{ + int32_t ret = 0; + __IO uint8_t random[4]; + *output_length = 0; + + /* Get Random byte */ + while ((*output_length < length) && (ret == 0)) + { + if (HAL_RNG_GenerateRandomNumber(&handle, (uint32_t *)random) != HAL_OK) + { + ret = -1; + } + else + { + for (uint8_t i = 0; (i < 4) && (*output_length < length) ; i++) + { + *output++ = random[i]; + *output_length += 1; + random[i] = 0; + } + } + } + /* Just be extra sure that we didn't do it wrong */ + if ((__HAL_RNG_GET_FLAG(&handle, (RNG_FLAG_CECS | RNG_FLAG_SECS))) != 0) + { + *output_length = 0; + } +} + +static void RNG_DeInit(void) +{ + /*Disable the RNG peripheral */ + HAL_RNG_DeInit(&handle); + /* RNG Peripheral clock disable - assume we're the only users of RNG */ + __HAL_RCC_RNG_CLK_DISABLE(); + + users = 0; +} + +int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) +{ + RNG_Init(); + RNG_GetBytes(output, len, olen); + RNG_DeInit(); + if (*olen != len) + { + return -1; + } + return 0; +} +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ + +#if defined(CA_ST_CRYPTOLIB_SUPP) +/** + * @brief CRC initialization + * This function release reset and clock CRC IP peripheral + * @retval None + */ +void CA_LL_CRC_Init(void) +{ + /* Force CRC into reset state */ + __HAL_RCC_CRC_FORCE_RESET(); + /* Release CRC from reset state */ + __HAL_RCC_CRC_RELEASE_RESET(); + /* Peripheral clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); +} + +#endif /* CA_ST_CRYPTOLIB_SUPP */ + +#endif /* CA_LOW_LEVEL_C */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/kms_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/kms_low_level.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/kms_low_level.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/kms_low_level.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/nvms_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/nvms_low_level.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_SECoreBin/Src/nvms_low_level.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/nvms_low_level.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/se_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/se_low_level.c new file mode 100644 index 00000000..cfec9ebf --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/Src/se_low_level.c @@ -0,0 +1,706 @@ +/** + ****************************************************************************** + * @file se_low_level.c + * @author MCD Application Team + * @brief Secure Engine Interface module. + * This file provides set of firmware functions to manage SE low level + * interface functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SE_LOW_LEVEL_C + +/* Includes ------------------------------------------------------------------*/ +#include "se_low_level.h" +#if defined(__ARMCC_VERSION) +#include "mapping_sbsfu.h" +#endif /* __CC_ARM */ +#include "se_exception.h" +#include "string.h" + +#ifdef KMS_ENABLED +#include "kms.h" +#include "kms_objects.h" +#include "kms_platf_objects_config.h" +#endif /* KMS_ENABLED */ + +/** @addtogroup SE Secure Engine + * @{ + */ +/** @defgroup SE_HARDWARE SE Hardware Interface + * @{ + */ + +/** @defgroup SE_HARDWARE_Private_Variables Private Variables + * @{ + */ +static CRC_HandleTypeDef CrcHandle; /*!< SE Crc Handle*/ + +static __IO uint32_t SE_DoubleECC_Error_Counter = 0U; + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Private_Functions Private Functions + * @{ + */ + +static uint32_t SE_LL_GetPage(uint32_t Address); +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Variables Exported Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Functions Exported Functions + * @{ + */ + +/** @defgroup SE_HARDWARE_Exported_CRC_Functions CRC Exported Functions + * @{ + */ + +/** + * @brief Set CRC configuration and call HAL CRC initialization function. + * @param None. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise + */ +SE_ErrorStatus SE_LL_CRC_Config(void) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + CrcHandle.Instance = CRC; + /* The input data are not inverted */ + CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + + /* The output data are not inverted */ + CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + + /* The Default polynomial is used */ + CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + /* The default init value is used */ + CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + /* The input data are 32-bit long words */ + CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS; + /* CRC Init*/ + if (HAL_CRC_Init(&CrcHandle) == HAL_OK) + { + e_ret_status = SE_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief Wrapper to HAL CRC initialization function. + * @param None + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_CRC_Init(void) +{ + /* CRC Peripheral clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + + return SE_LL_CRC_Config(); +} + +/** + * @brief Wrapper to HAL CRC de-initialization function. + * @param None + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_CRC_DeInit(void) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + if (HAL_CRC_DeInit(&CrcHandle) == HAL_OK) + { + /* Initialization OK */ + e_ret_status = SE_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief Wrapper to HAL CRC Calculate function. + * @param pBuffer: pointer to data buffer. + * @param uBufferLength: buffer length in 32-bits word. + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +uint32_t SE_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t uBufferLength) +{ + return HAL_CRC_Calculate(&CrcHandle, pBuffer, uBufferLength); +} + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_FLASH_Functions FLASH Exported Functions + * @{ + */ + +/** + * @brief This function does an erase of nb pages in user flash area + * @param pStart: pointer to user flash area + * @param Length: number of bytes. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_FLASH_Erase(uint8_t *pStart, uint32_t Length) +{ + uint32_t page_error = 0U; + uint32_t start = (uint32_t)pStart; + FLASH_EraseInitTypeDef p_erase_init; + SE_ErrorStatus e_ret_status = SE_SUCCESS; + + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + /* Fill EraseInit structure*/ + p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + p_erase_init.Page = SE_LL_GetPage(start); + p_erase_init.NbPages = SE_LL_GetPage(start + Length - 1U) - p_erase_init.Page + 1U; + if (HAL_FLASHEx_Erase(&p_erase_init, &page_error) != HAL_OK) + { + e_ret_status = SE_ERROR; + } + + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + (void)HAL_FLASH_Lock(); + } + else + { + e_ret_status = SE_ERROR; + } + + return e_ret_status; +} + +/** + * @brief Write in Flash protected area + * @param pDestination pointer to destination area in Flash + * @param pSource pointer to input buffer + * @param Length number of bytes to be written + * @retval SE_SUCCESS if successful, otherwise SE_ERROR + */ + +SE_ErrorStatus SE_LL_FLASH_Write(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + SE_ErrorStatus ret = SE_SUCCESS; + uint32_t i; + uint32_t verified = 0U; + uint32_t destination = (uint32_t)pDestination; + uint32_t source = (uint32_t)pSource; + + if (Length == 0U) + { + return SE_ERROR; + } + + /* Area should be inside 1 of the firmware image headers */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((destination >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((destination + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + verified = 1U; + } + } + if (verified == 0U) + { + return SE_ERROR; + } + + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + for (i = 0U; i < Length; i += 8U) + { + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (destination + i), *(uint64_t *)(source + i)) != HAL_OK) + { + ret = SE_ERROR; + break; + } + } + + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) */ + (void)HAL_FLASH_Lock(); + } + else + { + ret = SE_ERROR; + } + return ret; +} + +/** + * @brief Read in Flash protected area + * @param pDestination: Start address for target location + * @param pSource: pointer on buffer with data to read + * @param Length: Length in bytes of data buffer + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + uint32_t source = (uint32_t)pSource; + SE_ErrorStatus e_ret_status = SE_ERROR; + uint32_t i; + uint32_t verified = 0U; + + /* Area should be inside 1 of the firmware image headers + or inside 1 of the download areas */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((source >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((source + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + verified = 1U; + } + } + + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { + if ((source >= SlotStartAdd[SLOT_DWL_1 + i]) && + ((source + Length) <= (SlotStartAdd[SLOT_DWL_1 + i] + SLOT_SIZE(SLOT_DWL_1)))) + { + verified = 1U; + } + } + + if (verified == 0U) + { + return SE_ERROR; + } + + SE_DoubleECC_Error_Counter = 0U; + /* Do not use memcpy from lib : ECC error should be checked at each loop */ + for (i = 0; (i < Length) && (SE_DoubleECC_Error_Counter == 0U); i++, pDestination++, pSource++) + { + *pDestination = *pSource; + } + if (SE_DoubleECC_Error_Counter == 0U) + { + e_ret_status = SE_SUCCESS; + } + SE_DoubleECC_Error_Counter = 0U; + return e_ret_status; +} + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_FLASH_EXT_Functions External FLASH Exported Functions + * @{ + */ + +/** + * @brief Initialization of external flash On The Fly DECryption (OTFDEC) + * @param pxSE_Metadata: Firmware metadata. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_FLASH_EXT_Decrypt_Init(SE_FwRawHeaderTypeDef *pxSE_Metadata) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(pxSE_Metadata); + return SE_SUCCESS; +} + +/** + * @} + */ + +/** + * @brief Check if an array is inside the RAM of the product + * @param Addr : address of array + * @param Length : length of array in byte + */ +SE_ErrorStatus SE_LL_Buffer_in_ram(void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if ((Length != 0U) && (!((0xFFFFFFFFUL - addr_start) < Length)) + && ((addr_end <= SB_REGION_RAM_END) && (addr_start >= (SE_REGION_RAM_END + 1U)))) + { + e_ret_status = SE_SUCCESS; + } + else + { + e_ret_status = SE_ERROR; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + return e_ret_status; +} + +/** + * @brief function checking if a buffer is in sbsfu ram. + * @param pBuff: address of buffer + * @param Length: length of buffer in bytes + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_Buffer_in_SBSFU_ram(const void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if ((Length != 0U) && (!((0xFFFFFFFFUL - addr_start) < Length)) + && ((addr_end <= SB_REGION_RAM_END) && (addr_start >= SB_REGION_RAM_START))) + { + e_ret_status = SE_SUCCESS; + } + else + { + e_ret_status = SE_ERROR; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + return e_ret_status; +} + +/** + * @brief function checking if a buffer is PARTLY in se ram. + * @param pBuff: address of buffer + * @param Length: length of buffer in bytes + * @retval SE_ErrorStatus SE_SUCCESS for buffer in NOT se ram, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_Buffer_part_of_SE_ram(const void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if (((Length != 0U) && (!(((addr_start < SE_REGION_RAM_START) && (addr_end < SE_REGION_RAM_START)) || + ((addr_start > SE_REGION_RAM_END) && (addr_end > SE_REGION_RAM_END))))) + || ((0xFFFFFFFFUL - addr_start) < Length)) + { + e_ret_status = SE_SUCCESS; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + else + { + e_ret_status = SE_ERROR; + } + return e_ret_status; +} + +/** + * @brief function checking if a buffer is PARTLY in se rom. + * @param pBuff: address of buffer + * @param Length: length of buffer in bytes + * @retval SE_ErrorStatus SE_SUCCESS for buffer in NOT se rom, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_Buffer_part_of_SE_rom(const void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if (((Length != 0U) && (!(((addr_start < SE_CODE_REGION_ROM_START) && (addr_end < SE_CODE_REGION_ROM_START)) + || ((addr_start > SE_CODE_REGION_ROM_END) && (addr_end > SE_CODE_REGION_ROM_END)) + ))) + || ((0xFFFFFFFFUL - addr_start) < Length)) + { + e_ret_status = SE_SUCCESS; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + else + { + e_ret_status = SE_ERROR; + } + return e_ret_status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SE_LOCK_KEYS_Exported_Functions + * @{ + */ + +/** + * @brief Lock the embedded keys used by SBSFU + * @param None + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise + */ +SE_ErrorStatus SE_LL_Lock_Keys(void) +{ +#ifdef KMS_ENABLED + uint32_t i_key_locked = 0U; + uint32_t i_ctrl = 0U; + +#ifdef KMS_INDEX_BLOBIMPORT_VERIFY + i_ctrl++; + if (KMS_LockKeyHandle(KMS_INDEX_BLOBIMPORT_VERIFY) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_INDEX_BLOBIMPORT_VERIFY */ +#ifdef KMS_INDEX_BLOBIMPORT_DECRYPT + i_ctrl++; + if (KMS_LockKeyHandle(KMS_INDEX_BLOBIMPORT_DECRYPT) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_INDEX_BLOBIMPORT_DECRYPT */ +#ifdef KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE */ + if(i_ctrl == i_key_locked) + { + return SE_SUCCESS; + } + else + { + return SE_ERROR; + } +#else /* KMS_ENABLED */ + return SE_SUCCESS; +#endif /* KMS_ENABLED */ +} +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Private_Functions + * @{ + */ + +/** + * @brief Gets the page of a given address + * @param Addr: Address of the FLASH Memory + * @retval The page of a given address + */ +static uint32_t SE_LL_GetPage(uint32_t Address) +{ + uint32_t page; + + if (Address < (FLASH_BASE + (FLASH_BANK_SIZE))) + { + /* Bank 1 */ + page = (Address - FLASH_BASE) / FLASH_PAGE_SIZE; + } + else + { + /* Bank 2 */ + page = (Address - (FLASH_BASE + (FLASH_BANK_SIZE))) / FLASH_PAGE_SIZE; + } + return page; +} + +/** + * @brief Gets the bank of a given address + * @param Addr: Address of the FLASH Memory + * @retval The bank of a given address + */ + + +/** + * @brief Get Link Register value (LR) + * @param None. + * @retval LR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_LR(void) +{ + register uint32_t result; + +#if defined ( __ICCARM__ ) || ( __GNUC__ ) + __ASM volatile("MOV %0, LR" : "=r"(result)); +#elif defined ( __CC_ARM ) + __ASM volatile("MOV result, __return_address()"); +#endif /* ( __ICCARM__ ) || ( __GNUC__ ) */ + + return result; +} + +/* + As this handler code relies on stack pointer position to manipulate the PC return value, it is important + not to use extra registers (on top of scratch registers), because it would change the stack pointer + position. Then compiler optimizations are customized to ensure that. +*/ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O1"))) +#endif /* __ICCARM__ */ + +/** + * @brief NMI Handler present for handling Double ECC NMI interrupt + * @param None. + * @retval None. + */ +void NMI_Handler(void) +{ + uint32_t *p_sp; + uint32_t lr; + uint16_t opcode_msb; + + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)) + { + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); + + /* Memorize error to ignore the read value */ + SE_DoubleECC_Error_Counter++; + + lr = __get_LR(); + + /* Check EXC_RETURN value in LR to know which SP was used prior entering exception */ + if (((lr) & (0xFU)) == 0xDU) + { + /* interrupted code was using Process Stack Pointer */ + p_sp = (uint32_t *)__get_PSP(); + } + else + { + /* interrupted code was using Main Stack Pointer */ + p_sp = (uint32_t *)__get_MSP(); + } + + /* Test caller mode T bit from CPSR in stack */ + if ((*(p_sp + 7U) & (1U << xPSR_T_Pos)) != 0U) + { + /* Thumb mode. + Test PC in stack. + If bits [15:11] of the halfword being decoded take any of the following values, + the halfword is the first halfword of a 32-bit instruction: 0b11101, 0b11110, 0b11111. + Otherwise, the halfword is a 16-bit instruction. + */ + opcode_msb = (*(uint16_t *)(*(p_sp + 6) & 0xFFFFFFFEU) & 0xF800U); + if ((opcode_msb == 0xE800U) || (opcode_msb == 0xF000U) || (opcode_msb == 0xF800U)) + { + /* execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + else + { + /* execute next instruction PC +2 */ + *(p_sp + 6U) += 2U; + } + } + else + { + /* ARM mode execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + } + else + { + /* This exception occurs for another reason than flash double ECC errors */ + SE_NMI_ExceptionHandler(); + } +} + +/** + * @brief Hard Fault Handler present for handling Double ECC Bus Fault interrupt + * @param None. + * @retvat void + */ +void HardFault_Handler(void) +{ + SE_NMI_ExceptionHandler(); +} + +/** + * @brief Cleanup SE CORE + * The function is called during SE_LOCK_RESTRICT_SERVICES. + * + */ +void SE_LL_CORE_Cleanup(void) +{ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/readme.txt new file mode 100644 index 00000000..205abd15 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_SECoreBin/readme.txt @@ -0,0 +1,107 @@ +/** + @page 1_Image_SECoreBin / Secure Engine Core binary generation. + + @verbatim + ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* + * @file readme.txt + * @brief Secure Engine Core binary generation. + * SE Core binary exports SE CallGate function entry point for + * FU Application. + ****************************************************************************** + * + * Copyright (c) 2017 STMicroelectronics. All rights reserved. + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + @endverbatim + +@par Application Description + +This application is used to generate Secure Engine Core binary file to be linked +with Boot & Firmware Update application (BFU). +SE Core binary exports a single entry point to SE CallGate function and a startup method for data initialization. +It is based on the Secure Engine Middleware. + +Generated SE Core Binary embeds Key Management Services accessible through this same single entry point using APIs +defined by tKMS interface. + +It has to be compiled before BFU project. + +Three cryptographic schemes are provided as example to illustrate the cryptographic operations. The default +cryptographic scheme uses both symmetric (AES-CBC) and asymmetric (ECDSA) cryptography. Two alternate schemes are +provided and can be selected thanks to SECBOOT_CRYPTO_SCHEME compiler switch named : + - SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 (default) + - SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + - SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM + +For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" +available from the STMicroelectronics microcontroller website www.st.com. + +@par Keywords + +Security, KMS, SBSFU + +@par Directory contents + + - 1_Image_SECoreBin/Src/ca_low_level.c Low level implementations of the Cryptographic API (CA) module + - 1_Image_SECoreBin/Src/kms_low_level.c Key Management Services low level interface + - 1_Image_SECoreBin/Src/nvms_low_level.c Non volatile memory storage low level interface + - 1_Image_SECoreBin/Src/se_low_level.c Low level interface + - 1_Image_SECoreBin/Inc/ca_conf.h Configuration for Cryptographic API (CA) module functionalities + - 1_Image_SECoreBin/Inc/ca_low_level.h Header for ca_low_level.c + - 1_Image_SECoreBin/Inc/kms_config.h Key Management Services configuration file + - 1_Image_SECoreBin/Inc/kms_low_level.h Header for kms_low_level.c + - 1_Image_SECoreBin/Inc/kms_mem_pool_def.h KMS memory pool definition file + - 1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern Header for Key Management Services embedded objects definitions pattern + Appropriate cryptographic scheme keys are injected into it by the prebuild script (see below) + - 1_Image_SECoreBin/Inc/kms_platf_objects_interface.h Header for Key Management Services embedded objects references (labels, IDs...) + Exported to KMS user to ease embedded object usage + - 1_Image_SECoreBin/Inc/mbed_crypto_config.h mbed-crypto configuration file + - 1_Image_SECoreBin/Inc/nvms_low_level.h Header for nvms_low_level.c + - 1_Image_SECoreBin/Inc/se_crypto_config.h Crypto scheme configuration (crypto scheme used by the bootloader) + - 1_Image_SECoreBin/Inc/se_def_metadata.h Firmware metadata (header) definition + - 1_Image_SECoreBin/Inc/se_low_level.h Header file for low level interface + - 1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h HAL configuration file + - 1_Image_SECoreBin/Binary/ECCKEY1.txt Private ECCDSA key for signature verification + - 1_Image_SECoreBin/Binary/nonce.bin Number used only once for firmware encryption + - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin Public key for AES CBC encryption + - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin Public key for AES GCM encryption + +@par Hardware and Software environment + + - This example runs on STM32WL55xx devices + - This example has been tested with NUCLEO-WL55JC RevC board and can be easily tailored to any other supported device and + development board. + - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware is a feature provided by + STM32Cube programmer available on www.st.com. + - Microsoft Windows has a limitation whereby paths to files and directories cannot be longer than 256 characters. + Paths to files exceeding that limits cause tools (e.g. compilers, shell scripts) to fail reading from or writing + to such files. As a workaround, it is advised to use the subst.exe command from within a command prompt to set up + a local drive out of an existing directory on the hard drive, such as: + C:\> subst X: \Firmware + + +@par IDE prebuild script + +In order to ease the development process, a prebuild script ("prebuild.bat") is integrated in each IDE project. +This preliminary processing is in charge of: + - determining the requested cryptographic scheme + - generating the appropriate keys in /kms_platf_objects_config.h (from injection of BFU & Blob importation + keys into the KMS embedded objects pattern file) + - generating the appropriate script to prepare the firmware image ("postbuild.bat") when building the UserApp project + +A known limitation of this integration occurs when you update a cryptographic parameter (for instance the cryptographic +key). The IDE does not track this update so you need to force the rebuild of the project manually. + +@par How to use it ? + +In order to generate Secure Engine Core binary file, you must do the following : + - Open your preferred toolchain + - Rebuild the project + + *

      © COPYRIGHT STMicroelectronics

      + */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/Project.ewd similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/Project.ewd rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/Project.ewd diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/Project.ewp new file mode 100644 index 00000000..bcf00fec --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/Project.ewp @@ -0,0 +1,1192 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_UserApp + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + cmd /C "cmd /C $PROJ_DIR$\..\..\1_Image_SECoreBin\EWARM\postbuild.bat "$PROJ_DIR$" "$TARGET_PATH$" "$PROJ_DIR$\UserApp.bin" 1 1" + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + User + + $PROJ_DIR$\..\Src\main.c + + + $PROJ_DIR$\..\Src\com.c + + + $PROJ_DIR$\..\Src\common.c + + + $PROJ_DIR$\..\Src\fw_update_app.c + + + $PROJ_DIR$\..\Src\se_user_code.c + + + $PROJ_DIR$\..\Src\test_protections.c + + + $PROJ_DIR$\..\Src\ymodem.c + + + $PROJ_DIR$\..\Src\flash_if.c + + + $PROJ_DIR$\..\Src\stm32wlxx_it.c + + + $PROJ_DIR$\..\Src\kms_object_update_app.c + + + $PROJ_DIR$\..\Src\tkms_app.c + + + $PROJ_DIR$\..\Src\tkms_app_derive_key.c + + + $PROJ_DIR$\..\Src\tkms_app_encrypt_decrypt.c + + + $PROJ_DIR$\..\Src\tkms_app_find.c + + + $PROJ_DIR$\..\Src\tkms_app_sign_verify.c + + + + EWARM + + $PROJ_DIR$\startup_stm32wl55xx_cm4.s + + + + + Drivers + + BSP + + STM32WLxx_Nucleo + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\BSP\STM32WLxx_Nucleo\stm32wlxx_nucleo.c + + + + + STM32WLxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cortex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_iwdg.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_exti.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c + + + + CMSIS + + $PROJ_DIR$\..\Src\system_stm32wlxx.c + + + + + Middlewares + + STM32_Secure_Engine + + $PROJ_DIR$\..\..\1_Image_BFU\EWARM\se_interface_appli.o + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s new file mode 100644 index 00000000..658ca8e5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s @@ -0,0 +1,509 @@ +;******************************************************************************** +;* File Name : startup_stm32wl55xx_cm4.s +;* Author : MCD Application Team +;* Description : M4 core vector table of the STM32WLxxxx devices for the +;* IAR (EWARM) toolchain. +;* +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* +;* Copyright (c) 2020(2021) STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +; +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD and PVM Interrupt + DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSRU Interrupts + DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt + DCD FLASH_IRQHandler ; FLASH global Interrupt + DCD RCC_IRQHandler ; RCC Interrupt + DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt + DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt + DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt + DCD EXTI3_IRQHandler ; EXTI Line 3 Interrupt + DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt + DCD ADC_IRQHandler ; ADC Interrupt + DCD DAC_IRQHandler ; DAC Interrupt + DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV Interrupt + DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts + DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt + DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt + DCD TIM2_IRQHandler ; TIM2 Global Interrupt + DCD TIM16_IRQHandler ; TIM16 Global Interrupt + DCD TIM17_IRQHandler ; TIM17 Global Interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt + DCD SPI1_IRQHandler ; SPI1 Interrupt + DCD SPI2_IRQHandler ; SPI2 Interrupt + DCD USART1_IRQHandler ; USART1 Interrupt + DCD USART2_IRQHandler ; USART2 Interrupt + DCD LPUART1_IRQHandler ; LPUART1 Interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 Global Interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 Global Interrupt + DCD EXTI15_10_IRQHandler ; EXTI Lines [15:10] Interrupt + DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 Global Interrupt + DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt + DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt + DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt + DCD HSEM_IRQHandler ; HSEM0 Interrupt + DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt + DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt + DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt + DCD AES_IRQHandler ; AES Interrupt + DCD RNG_IRQHandler ; RNG1 Interrupt + DCD PKA_IRQHandler ; PKA Interrupt + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt + DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_PVM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_PVM_IRQHandler + B PVD_PVM_IRQHandler + + PUBWEAK TAMP_STAMP_LSECSS_SSRU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_STAMP_LSECSS_SSRU_IRQHandler + B TAMP_STAMP_LSECSS_SSRU_IRQHandler + + PUBWEAK RTC_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_WKUP_IRQHandler + B RTC_WKUP_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel2_IRQHandler + B DMA1_Channel2_IRQHandler + + PUBWEAK DMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel3_IRQHandler + B DMA1_Channel3_IRQHandler + + PUBWEAK DMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel4_IRQHandler + B DMA1_Channel4_IRQHandler + + PUBWEAK DMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel5_IRQHandler + B DMA1_Channel5_IRQHandler + + PUBWEAK DMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel6_IRQHandler + B DMA1_Channel6_IRQHandler + + PUBWEAK DMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel7_IRQHandler + B DMA1_Channel7_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK DAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC_IRQHandler + B DAC_IRQHandler + + PUBWEAK C2SEV_PWR_C2H_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +C2SEV_PWR_C2H_IRQHandler + B C2SEV_PWR_C2H_IRQHandler + + PUBWEAK COMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP_IRQHandler + B COMP_IRQHandler + + PUBWEAK EXTI9_5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_5_IRQHandler + B EXTI9_5_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK EXTI15_10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_10_IRQHandler + B EXTI15_10_IRQHandler + + PUBWEAK RTC_Alarm_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Alarm_IRQHandler + B RTC_Alarm_IRQHandler + + PUBWEAK LPTIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM3_IRQHandler + B LPTIM3_IRQHandler + + PUBWEAK SUBGHZSPI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZSPI_IRQHandler + B SUBGHZSPI_IRQHandler + + PUBWEAK IPCC_C1_RX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_RX_IRQHandler + B IPCC_C1_RX_IRQHandler + + PUBWEAK IPCC_C1_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_TX_IRQHandler + B IPCC_C1_TX_IRQHandler + + PUBWEAK HSEM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HSEM_IRQHandler + B HSEM_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK SUBGHZ_Radio_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZ_Radio_IRQHandler + B SUBGHZ_Radio_IRQHandler + + PUBWEAK AES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AES_IRQHandler + B AES_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK PKA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PKA_IRQHandler + B PKA_IRQHandler + + PUBWEAK DMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel1_IRQHandler + B DMA2_Channel1_IRQHandler + + PUBWEAK DMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel2_IRQHandler + B DMA2_Channel2_IRQHandler + + PUBWEAK DMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel3_IRQHandler + B DMA2_Channel3_IRQHandler + + PUBWEAK DMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel4_IRQHandler + B DMA2_Channel4_IRQHandler + + PUBWEAK DMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel5_IRQHandler + B DMA2_Channel5_IRQHandler + + PUBWEAK DMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel6_IRQHandler + B DMA2_Channel6_IRQHandler + + PUBWEAK DMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel7_IRQHandler + B DMA2_Channel7_IRQHandler + + PUBWEAK DMAMUX1_OVR_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMAMUX1_OVR_IRQHandler + B DMAMUX1_OVR_IRQHandler + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf new file mode 100644 index 00000000..ae672ac8 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf @@ -0,0 +1,43 @@ +/*###ICF### Set of symbols used in UserApp project ****/ + +define memory mem with size = 4G; + +/******************************************************************************/ +/* Include of SBSFU symbols file */ +/* (Project>Options>Linker>Extra Options --config_search option is used to */ +/* specify the the directory to search for include files */ +/******************************************************************************/ +include "mapping_sbsfu.icf"; +include "mapping_fwimg.icf"; + +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = __ICFEDIT_SLOT_Active_1_start__ + 512; +define symbol __ICFEDIT_region_ROM_end__ = __ICFEDIT_SLOT_Active_1_end__ ; +define symbol __ICFEDIT_region_RAM_start__ = __ICFEDIT_SE_region_RAM_end__ + 1; +define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x200; + +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +/* to make sure the binary size is a multiple of the AES block size (16 bytes) and WL flash writing unit (8 bytes) */ +define root section aes_block_padding with alignment=16 +{ +udata8 "Force Alignment"; +pad_to 16; +}; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_region_ROM_start__ { readonly section .intvec }; + +place in ROM_region { readonly, last section aes_block_padding }; +place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/com.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/com.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/com.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/com.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/common.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/common.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/common.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/common.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/flash_if.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/flash_if.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/flash_if.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/flash_if.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/fw_update_app.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/fw_update_app.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/fw_update_app.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/fw_update_app.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/main.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/main.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/main.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/main.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/se_user_code.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/se_user_code.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/se_user_code.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/se_user_code.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/sfu_app_new_image.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/sfu_app_new_image.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/sfu_app_new_image.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/sfu_app_new_image.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/stm32wlxx_hal_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/stm32wlxx_hal_conf.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/stm32wlxx_hal_conf.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/stm32wlxx_hal_conf.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/stm32wlxx_it.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/stm32wlxx_it.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/stm32wlxx_it.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/stm32wlxx_it.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h new file mode 100644 index 00000000..0af7b23e --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * @file stm32wlxx_nucleo_conf.h + * @author MCD Application Team + * @brief STM32WLxx_Nucleo board configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2020(-2021) STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLXX_NUCLEO_CONF_H +#define STM32WLXX_NUCLEO_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wlxx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WLXX_NUCLEO + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG CONFIG + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG_Exported_Constants Exported Constants + * @{ + */ +/* COM usage define */ +#define USE_BSP_COM_FEATURE 0U + +/* COM log define */ +#define USE_COM_LOG 0U + +/* IRQ priorities */ +#define BSP_BUTTON_SWx_IT_PRIORITY 15U + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLXX_NUCLEO_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/test_protections.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/test_protections.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/test_protections.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/test_protections.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/tkms_app.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/tkms_app.h new file mode 100644 index 00000000..da212f0b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/tkms_app.h @@ -0,0 +1,63 @@ +/** + ****************************************************************************** + * @file tkms_app.h + * @author MCD Application Team + * @brief This file contains definitions for tkms application examples. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef KMS_APP_H +#define KMS_APP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "app_sfu.h" + +/* Exported macros -----------------------------------------------------------*/ +#if defined(SFU_IWDG_PROTECT_ENABLE) +/* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload register */ +#define INVOKE_SCHEDULE_NEEDS() \ + do { \ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); \ + } while(0); +#else +#define INVOKE_SCHEDULE_NEEDS() \ + do { \ + ; \ + } while(0); +#endif /* SFU_IWDG_PROTECT_ENABLE */ + + + +/* Exported functions ------------------------------------------------------- */ +void tkms_app_menu(void); +void tkms_buff2str(uint8_t *pbuff, uint8_t *pstr, uint32_t length); + +CK_RV tkms_app_encrypt_decrypt_aes_gcm(uint32_t length, uint8_t *pClearMessage); +CK_RV tkms_app_encrypt_decrypt_aes_cbc(uint32_t length, uint8_t *pClearMessage); +CK_RV tkms_app_sign_verify_rsa(uint32_t length, uint8_t *pMessage); +CK_RV tkms_app_derive_key(uint32_t length, uint8_t *pMessage); +CK_RV tkms_app_find(void); + +#ifdef __cplusplus +} +#endif + +#endif /* KMS_APP_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/ymodem.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/ymodem.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Inc/ymodem.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Inc/ymodem.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/Project.uvoptx new file mode 100644 index 00000000..3fcb2555 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/Project.uvoptx @@ -0,0 +1,759 @@ + + + + 1.0 + +
      ### uVision Project, (C) Keil Software
      + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32WL55JC_Nucleo_1_Image_UserApp + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + STM32WL55JC_Nucleo/List\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + .\STM32WL_CM4.ini + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=98,207,509,709,0)(1007=673,180,880,401,0)(1008=566,409,942,645,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + + + + 1 + 2 + 0x2000A400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + System Viewer\DBGMCU + 35904 + + + System Viewer\NVIC + 35901 + + + System Viewer\SCB + 35905 + + + System Viewer\SYSCFG + 35903 + + + System Viewer\SYSCFG_continue + 35902 + + + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + .\startup_stm32wl55xx_cm4.s + startup_stm32wl55xx_cm4.s + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ../Src/com.c + com.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ../Src/common.c + common.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ../Src/flash_if.c + flash_if.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ../Src/fw_update_app.c + fw_update_app.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ../Src/kms_object_update_app.c + kms_object_update_app.c + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ../Src/main.c + main.c + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ../Src/se_user_code.c + se_user_code.c + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ../Src/stm32wlxx_it.c + stm32wlxx_it.c + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ../Src/test_protections.c + test_protections.c + 0 + 0 + + + 2 + 11 + 1 + 0 + 0 + 0 + ../Src/tkms_app.c + tkms_app.c + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ../Src/tkms_app_derive_key.c + tkms_app_derive_key.c + 0 + 0 + + + 2 + 13 + 1 + 0 + 0 + 0 + ../Src/tkms_app_encrypt_decrypt.c + tkms_app_encrypt_decrypt.c + 0 + 0 + + + 2 + 14 + 1 + 0 + 0 + 0 + ../Src/tkms_app_find.c + tkms_app_find.c + 0 + 0 + + + 2 + 15 + 1 + 0 + 0 + 0 + ../Src/tkms_app_sign_verify.c + tkms_app_sign_verify.c + 0 + 0 + + + 2 + 16 + 1 + 0 + 0 + 0 + ../Src/ymodem.c + ymodem.c + 0 + 0 + + + + + Doc + 1 + 0 + 0 + 0 + + 3 + 17 + 5 + 0 + 0 + 0 + ../readme.txt + readme.txt + 0 + 0 + + + + + Drivers/BSP/STM32WLxx_Nucleo + 0 + 0 + 0 + 0 + + 4 + 18 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + stm32wlxx_nucleo.c + 0 + 0 + + + + + Drivers/STM32WLxx_HAL_Driver + 0 + 0 + 0 + 0 + + 5 + 19 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + stm32wlxx_hal.c + 0 + 0 + + + 5 + 20 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + stm32wlxx_hal_cortex.c + 0 + 0 + + + 5 + 21 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + stm32wlxx_hal_crc.c + 0 + 0 + + + 5 + 22 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + stm32wlxx_hal_crc_ex.c + 0 + 0 + + + 5 + 23 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + stm32wlxx_hal_dma.c + 0 + 0 + + + 5 + 24 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c + stm32wlxx_hal_dma_ex.c + 0 + 0 + + + 5 + 25 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + stm32wlxx_hal_exti.c + 0 + 0 + + + 5 + 26 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + stm32wlxx_hal_flash.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + stm32wlxx_hal_flash_ex.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + stm32wlxx_hal_gpio.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + stm32wlxx_hal_iwdg.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + stm32wlxx_hal_pwr.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + stm32wlxx_hal_pwr_ex.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + stm32wlxx_hal_rcc.c + 0 + 0 + + + 5 + 33 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + stm32wlxx_hal_rcc_ex.c + 0 + 0 + + + 5 + 34 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + stm32wlxx_hal_rtc.c + 0 + 0 + + + 5 + 35 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + stm32wlxx_hal_rtc_ex.c + 0 + 0 + + + 5 + 36 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + stm32wlxx_hal_uart.c + 0 + 0 + + + 5 + 37 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + stm32wlxx_hal_uart_ex.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 6 + 38 + 1 + 0 + 0 + 0 + ../Src/system_stm32wlxx.c + system_stm32wlxx.c + 0 + 0 + + + + + Middlewares/STM32_Secure_Engine + 0 + 0 + 0 + 0 + + 7 + 39 + 3 + 0 + 0 + 0 + ..\..\1_Image_BFU\MDK-ARM\STM32WL55JC_Nucleo\Exe\se_interface_appli.txt + se_interface_appli.txt + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..0b7cb8ce --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/Project.uvprojx @@ -0,0 +1,632 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_UserApp + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + UserApp + 1 + 0 + 0 + 1 + 1 + STM32WL55JC_Nucleo/List\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 1 + fromelf #L --bincombined --output=$L../../@L.bin + .\..\..\1_Image_SECoreBin\MDK-ARM\postbuild.bat . #L @L.bin 1 1 + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED,DISABLE_IMAGE_STATE_HANDLING + + ../Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../1_Image_SECoreBin/Inc;../../1_Image_BFU/BFU/App;../../Linker_Common/MDK-ARM;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface;../../../../../../Drivers/BSP/STM32WLxx_Nucleo + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + .\UserApp.sct + + + + + + + + + + + Application/MDK-ARM + + + startup_stm32wl55xx_cm4.s + 2 + .\startup_stm32wl55xx_cm4.s + + + + + Application/User + + + com.c + 1 + ../Src/com.c + + + common.c + 1 + ../Src/common.c + + + flash_if.c + 1 + ../Src/flash_if.c + + + fw_update_app.c + 1 + ../Src/fw_update_app.c + + + kms_object_update_app.c + 1 + ../Src/kms_object_update_app.c + + + main.c + 1 + ../Src/main.c + + + se_user_code.c + 1 + ../Src/se_user_code.c + + + stm32wlxx_it.c + 1 + ../Src/stm32wlxx_it.c + + + test_protections.c + 1 + ../Src/test_protections.c + + + tkms_app.c + 1 + ../Src/tkms_app.c + + + tkms_app_derive_key.c + 1 + ../Src/tkms_app_derive_key.c + + + tkms_app_encrypt_decrypt.c + 1 + ../Src/tkms_app_encrypt_decrypt.c + + + tkms_app_find.c + 1 + ../Src/tkms_app_find.c + + + tkms_app_sign_verify.c + 1 + ../Src/tkms_app_sign_verify.c + + + ymodem.c + 1 + ../Src/ymodem.c + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Drivers/BSP/STM32WLxx_Nucleo + + + stm32wlxx_nucleo.c + 1 + ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + + + Drivers/STM32WLxx_HAL_Driver + + + stm32wlxx_hal.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + stm32wlxx_hal_cortex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + stm32wlxx_hal_crc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + stm32wlxx_hal_crc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + stm32wlxx_hal_dma.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + + + stm32wlxx_hal_dma_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c + + + stm32wlxx_hal_exti.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + stm32wlxx_hal_flash.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + stm32wlxx_hal_flash_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + stm32wlxx_hal_gpio.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + stm32wlxx_hal_iwdg.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + stm32wlxx_hal_pwr.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + stm32wlxx_hal_pwr_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + stm32wlxx_hal_rcc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + stm32wlxx_hal_rcc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + stm32wlxx_hal_rtc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + stm32wlxx_hal_rtc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + stm32wlxx_hal_uart.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + stm32wlxx_hal_uart_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + + + Drivers/CMSIS + + + system_stm32wlxx.c + 1 + ../Src/system_stm32wlxx.c + + + + + Middlewares/STM32_Secure_Engine + + + se_interface_appli.txt + 3 + ..\..\1_Image_BFU\MDK-ARM\STM32WL55JC_Nucleo\Exe\se_interface_appli.txt + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/UserApp.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/UserApp.sct new file mode 100644 index 00000000..e0efa2a0 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/UserApp.sct @@ -0,0 +1,29 @@ +#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0plus -E -xc +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* +#include "..\..\Linker_Common\MDK-ARM\mapping_sbsfu.h" +#include "..\..\Linker_Common\MDK-ARM\mapping_fwimg.h" + +LR_ROM (SLOT_ACTIVE_1_START + 0x200) { ; 0x200 = IMAGE_OFFSET + vector_start (SLOT_ACTIVE_1_START + 0x200) FIXED VECTOR_SIZE { + *.o (RESET, +First) + } + ROM_region +0 { + *(InRoot$$Sections) + .ANY (+RO) + } +; SBSFU RAM area is reused for UserApp + RAM_region SB_REGION_RAM_START SB_RAM_REGION_SIZE { + .ANY (STACK) + .ANY (HEAP) + .ANY (+RW +ZI) + } +} + +; extra ROM region to make sure the binary size is a multiple of the AES block size (16 bytes) and WL flash writing unit (8 bytes) +LR_ROM1(+0) ALIGN(16) { + ForAlignment +0 { + startup_stm32wl55xx_cm4.o (ALIGNTOAESBLOCK,+Last) + } +} diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/startup_stm32wl55xx_cm4.s similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/MDK-ARM/startup_stm32wl55xx_cm4.s rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/MDK-ARM/startup_stm32wl55xx_cm4.s diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/.cproject new file mode 100644 index 00000000..600b23f4 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/.cproject @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/.project new file mode 100644 index 00000000..8787579a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/.project @@ -0,0 +1,231 @@ + + + 1_Image_UserApp + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doc/readme.txt + 1 + $%7BPARENT-1-PROJECT_LOC%7D/readme.txt + + + Application/User/com.c + 1 + PARENT-1-PROJECT_LOC/Src/com.c + + + Application/User/common.c + 1 + PARENT-1-PROJECT_LOC/Src/common.c + + + Application/User/flash_if.c + 1 + PARENT-1-PROJECT_LOC/Src/flash_if.c + + + Application/User/fw_update_app.c + 1 + PARENT-1-PROJECT_LOC/Src/fw_update_app.c + + + Application/User/kms_object_update_app.c + 1 + PARENT-1-PROJECT_LOC/Src/kms_object_update_app.c + + + Application/User/main.c + 1 + PARENT-1-PROJECT_LOC/Src/main.c + + + Application/User/se_user_code.c + 1 + PARENT-1-PROJECT_LOC/Src/se_user_code.c + + + Application/User/stm32wlxx_it.c + 1 + PARENT-1-PROJECT_LOC/Src/stm32wlxx_it.c + + + Application/User/test_protections.c + 1 + PARENT-1-PROJECT_LOC/Src/test_protections.c + + + Application/User/tkms_app.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app.c + + + Application/User/tkms_app_derive_key.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_derive_key.c + + + Application/User/tkms_app_encrypt_decrypt.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_encrypt_decrypt.c + + + Application/User/tkms_app_find.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_find.c + + + Application/User/tkms_app_sign_verify.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_sign_verify.c + + + Application/User/ymodem.c + 1 + PARENT-1-PROJECT_LOC/Src/ymodem.c + + + Drivers/CMSIS/system_stm32wlxx.c + 1 + PARENT-1-PROJECT_LOC/Src/system_stm32wlxx.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cortex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_dma.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_dma_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_exti.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gpio.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gtzc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gtzc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_iwdg.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + Middlewares/STM32_Secure_Engine/se_interface_app.o + 1 + PARENT-2-PROJECT_LOC/1_Image_BFU/STM32CubeIDE/Debug/se_interface_app.o + + + Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + 1 + PARENT-6-PROJECT_LOC/Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_End_Node/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_End_Node/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/Application/User/syscalls.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/Application/User/syscalls.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/Application/User/syscalls.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/Application/User/syscalls.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/Application/User/sysmem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/Application/User/sysmem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/Application/User/sysmem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/Application/User/sysmem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/UserApp.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/UserApp.ld similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/STM32CubeIDE/UserApp.ld rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/STM32CubeIDE/UserApp.ld diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/com.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/com.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/com.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/com.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/common.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/common.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/common.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/common.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/flash_if.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/flash_if.c new file mode 100644 index 00000000..6ecbce70 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/flash_if.c @@ -0,0 +1,361 @@ +/** + ****************************************************************************** + * @file flash_if.c + * @author MCD Application Team + * @brief FLASH Interface module. + * This file provides set of firmware functions to manage Flash + * Interface functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup USER_APP_COMMON Common + * @{ + */ +/* Includes ------------------------------------------------------------------*/ +#include "flash_if.h" +#include "string.h" +#include + +/* Uncomment the line below if you want some debug logs */ +#define FLASH_IF_DBG +#ifdef FLASH_IF_DBG +#define FLASH_IF_TRACE printf +#else +#define FLASH_IF_TRACE(...) +#endif /* FLASH_IF_DBG */ + + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define NB_PAGE_SECTOR_PER_ERASE 2U /*!< Nb page erased per erase */ +#define EXTERNAL_FLASH_ADDRESS 0x90000000U + + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + + +/* Private function prototypes -----------------------------------------------*/ +static uint32_t GetPage(uint32_t uAddr); +static HAL_StatusTypeDef FLASH_INT_If_Clear_Error(void); + +/* Public functions : wrapper ---------------------------------------------------------*/ + +/** + * @brief Initialize internal and external flash interface (OSPI/QSPI) + * @param none + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_If_Init(void) +{ + HAL_StatusTypeDef e_ret_status = HAL_OK; + + e_ret_status = FLASH_INT_Init(); + if (e_ret_status == HAL_OK) + { + e_ret_status = FLASH_EXT_Init(); + } + return e_ret_status; +} +/** + * @brief Depending on start address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pStart: flash address to be erased + * @param uLength: number of bytes + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_If_Erase_Size(void *pStart, uint32_t uLength) +{ + /* Check Flash start address */ + if ((uint32_t) pStart < EXTERNAL_FLASH_ADDRESS) + { + return FLASH_INT_If_Erase_Size(pStart, uLength); + } + else + { + return FLASH_EXT_If_Erase_Size(pStart, uLength); + } +} + +/** + * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pDestination: flash address to write + * @param pSource: pointer on buffer with data to write + * @param uLength: number of bytes + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_If_Write(void *pDestination, const void *pSource, uint32_t uLength) +{ + /* Check Flash destination address */ + if ((uint32_t) pDestination < EXTERNAL_FLASH_ADDRESS) + { + return FLASH_INT_If_Write(pDestination, pSource, uLength); + } + else + { + return FLASH_EXT_If_Write(pDestination, pSource, uLength); + } +} + +/** + * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver + * @brief Depending on source address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pDestination: pointer on buffer to store data + * @param pSource: flash address to read + * @param uLength: number of bytes + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_If_Read(void *pDestination, const void *pSource, uint32_t uLength) +{ + /* Check Flash source address */ + if ((uint32_t) pSource < EXTERNAL_FLASH_ADDRESS) + { + return FLASH_INT_If_Read(pDestination, pSource, uLength); + } + else + { + return FLASH_EXT_If_Read(pDestination, pSource, uLength); + } +} + +/* Public functions : internal flash --------------------------------------------------------- */ +/** + * @brief This function initialize the internal flash interface if required + * @param none + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_INT_Init(void) +{ + return HAL_OK; +} + +/** + * @brief This function does an erase of n (depends on Length) pages in user flash area + * @param pStart: Start of user flash area + * @param uLength: number of bytes. + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_INT_If_Erase_Size(void *pStart, uint32_t uLength) +{ + uint32_t page_error = 0U; + uint32_t uStart = (uint32_t)pStart; + FLASH_EraseInitTypeDef x_erase_init; + HAL_StatusTypeDef e_ret_status = HAL_ERROR; + uint32_t first_page = 0U; + uint32_t nb_pages = 0U; + uint32_t chunk_nb_pages; + + /* Clear error flags raised during previous operation */ + e_ret_status = FLASH_INT_If_Clear_Error(); + + if (e_ret_status == HAL_OK) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + first_page = GetPage(uStart); + /* Get the number of pages to erase from 1st page */ + nb_pages = GetPage(uStart + uLength - 1U) - first_page + 1U; + x_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + /* Erase flash per NB_PAGE_SECTOR_PER_ERASE to avoid watch-dog */ + do + { + chunk_nb_pages = (nb_pages >= NB_PAGE_SECTOR_PER_ERASE) ? NB_PAGE_SECTOR_PER_ERASE : nb_pages; + x_erase_init.Page = first_page; + x_erase_init.NbPages = chunk_nb_pages; + first_page += chunk_nb_pages; + nb_pages -= chunk_nb_pages; + if (HAL_FLASHEx_Erase(&x_erase_init, &page_error) != HAL_OK) + { + HAL_FLASH_GetError(); + e_ret_status = HAL_ERROR; + } + /* Refresh Watchdog */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + } while (nb_pages > 0); + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + HAL_FLASH_Lock(); + + } + else + { + e_ret_status = HAL_ERROR; + } + } + + return e_ret_status; +} + +/** + * @brief This function writes a data buffer in flash (data are 32-bit aligned). + * @note After writing data buffer, the flash content is checked. + * @param pDestination: Start address for target location. It has to be 8 bytes aligned. + * @param pSource: pointer on buffer with data to write + * @param uLength: Length of data buffer in bytes. It has to be 8 bytes aligned. + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_INT_If_Write(void *pDestination, const void *pSource, uint32_t uLength) +{ + HAL_StatusTypeDef e_ret_status = HAL_ERROR; + uint32_t i = 0U; + uint32_t pdata = (uint32_t)pSource; + + /* Clear error flags raised during previous operation */ + e_ret_status = FLASH_INT_If_Clear_Error(); + + if (e_ret_status == HAL_OK) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() != HAL_OK) + { + return HAL_ERROR; + + } + else + { + /* DataLength must be a multiple of 64 bit */ + for (i = 0U; i < uLength; i += 8U) + { + /* Device voltage range supposed to be [2.7V to 3.6V], the operation will + be done by word */ + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)pDestination, *((uint64_t *)(pdata + i))) + == HAL_OK) + { + /* Check the written value */ + if (*(uint64_t *)pDestination != *(uint64_t *)(pdata + i)) + { + /* Flash content doesn't match SRAM content */ + e_ret_status = HAL_ERROR; + break; + } + /* Increment FLASH Destination address */ + pDestination = (void *)((uint32_t)pDestination + 8U); + } + else + { + /* Error occurred while writing data in Flash memory */ + e_ret_status = HAL_ERROR; + break; + } + } + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + HAL_FLASH_Lock(); + } + } + return e_ret_status; +} + +/** + * @brief This function reads flash + * @param pDestination: Start address for target location + * @param pSource: flash address to read + * @param uLength: number of bytes + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_INT_If_Read(void *pDestination, const void *pSource, uint32_t uLength) +{ + memcpy(pDestination, pSource, uLength); + return HAL_OK; +} + +/* Public functions : external flash ---------------------------------------------------------*/ + +HAL_StatusTypeDef FLASH_EXT_Init(void) +{ + return HAL_OK; +} + +/* No external flash available on this product + ==> return SFU_ERROR */ + +HAL_StatusTypeDef FLASH_EXT_If_Erase_Size(void *pStart, uint32_t uLength) +{ + return HAL_ERROR; +} + +HAL_StatusTypeDef FLASH_EXT_If_Write(void *pDestination, const void *pSource, uint32_t uLength) +{ + return HAL_ERROR; +} + +HAL_StatusTypeDef FLASH_EXT_If_Read(void *pDestination, const void *pSource, uint32_t uLength) +{ + return HAL_ERROR; +} + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Clear error flags raised during previous operation + * @param None + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_INT_If_Clear_Error(void) +{ + HAL_StatusTypeDef ret = HAL_ERROR; + + /* Unlock the Program memory */ + if (HAL_FLASH_Unlock() == HAL_OK) + { + + /* Clear all FLASH flags */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); + /* Unlock the Program memory */ + if (HAL_FLASH_Lock() == HAL_OK) + { + ret = HAL_OK; + } +#ifdef FLASH_IF_DBG + else + { + FLASH_IF_TRACE("[FLASH_IF] Lock failure\r\n"); + } +#endif /* FLASH_IF_DBG */ + } +#ifdef FLASH_IF_DBG + else + { + FLASH_IF_TRACE("[FLASH_IF] Unlock failure\r\n"); + } +#endif /* FLASH_IF_DBG */ + return ret; +} + +/** + * @brief Gets the page of a given address + * @param Addr: Address of the FLASH Memory + * @retval The page of a given address + */ +uint32_t GetPage(uint32_t Addr) +{ + uint32_t page = 0U; + + page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE; + + return page; +} + + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/fw_update_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/fw_update_app.c new file mode 100644 index 00000000..f29c01c3 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/fw_update_app.c @@ -0,0 +1,144 @@ +/** + ****************************************************************************** + * @file fw_update_app.c + * @author MCD Application Team + * @brief Firmware Update module. + * This file provides set of firmware functions to manage Firmware + * Update functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#include "se_def.h" +#include "com.h" +#include "common.h" +#include "flash_if.h" +#include "stm32wlxx_hal.h" +#include "stm32wlxx_nucleo.h" +#include "fw_update_app.h" +#include "se_interface_application.h" +#include "sfu_fwimg_regions.h" +#include "string.h" +#if defined(__ARMCC_VERSION) +#include "mapping_sbsfu.h" +#elif defined (__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#elif defined(__CC_ARM) +#include "mapping_fwimg.h" +#include "mapping_sbsfu.h" +#endif /* __ARMCC_VERSION */ +#include "ymodem.h" + +/* Private defines -----------------------------------------------------------*/ + +#define ALL_SLOTS 255U /*!< Validate all new firmware installed in a single request */ +/* Global variables ----------------------------------------------------------*/ + + +/* Private function prototypes -----------------------------------------------*/ + + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Run FW Update process. + * @param None + * @retval HAL Status. + */ +#if defined(EXTERNAL_LOADER) +void FW_UPDATE_Run(void) +{ + /* Print Firmware Update welcome message */ + printf("\r\n================ New Fw Download =========================\r\n\n"); + + /* Standalone loader communication : execution requested */ + STANDALONE_LOADER_STATE = STANDALONE_LOADER_DWL_REQ; + + NVIC_SystemReset(); +} + +#else +void FW_UPDATE_Run(void) +{ + printf(" Feature not supported ! \r\n"); +} + +#endif + + +#if defined(EXTERNAL_LOADER) +/** + * @brief Run Multiple FW Update process. + * @param None + * @retval None. + */ +void FW_UPDATE_MULTIPLE_RunMenu(void) +{ + printf(" Feature not supported ! \r\n"); +} + +#else +/** + * @brief Run Multiple FW Update process. + * @param None + * @retval None. + */ +void FW_UPDATE_MULTIPLE_RunMenu(void) +{ + printf(" Feature not supported ! \r\n"); +} + +#endif + + +#if defined(EXTERNAL_LOADER) +/** + * @brief Run validation of a FW image menu. + * @param None + * @retval None. + */ +void FW_VALIDATE_RunMenu(void) +{ + printf(" Feature not supported ! \r\n"); +} + +#else +/** + * @brief Run validation of a FW image menu. + * @param None + * @retval None. + */ +void FW_VALIDATE_RunMenu(void) +{ + printf(" Feature not supported ! \r\n"); +} + +#endif + + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/kms_object_update_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/kms_object_update_app.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/kms_object_update_app.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/kms_object_update_app.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/main.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/main.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/main.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/main.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/se_user_code.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/se_user_code.c new file mode 100644 index 00000000..894f1ed6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/se_user_code.c @@ -0,0 +1,191 @@ +/** + ****************************************************************************** + * @file se_user_code.c + * @author MCD Application Team + * @brief Secure Engine User code example module. + * This file demonstrates how to call user defined services running + * in Secure Engine. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "se_def.h" +#include "com.h" +#include "common.h" +#include "stm32wlxx_hal.h" +#include "stm32wlxx_nucleo.h" +#include "se_user_code.h" +#include "se_interface_application.h" +#include "sfu_fwimg_regions.h" +#include /* needed for memset */ + + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup SE_USER_CODE Secure Engine User Code Example + * @brief Example of user defined code running in Secure Engine. + * This code provides user defined services to the user application. + * @{ + */ + +/** @defgroup SE_USER_CODE_Private_Variables Private Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup SE_USER_CODE_Private_Functions Private Functions + * @{ + */ + +/** + * @brief Display the SE_USER_CODE Menu choices on hyperterminal + * @param None. + * @retval None. + */ +static void SE_USER_CODE_PrintMenu(void) +{ + printf("\r\n=== Call User Defined Code running in Secure Engine ===\r\n\n"); + printf(" Get firmware information of SLOT_ACTIVE_1 ------------- 1\r\n\n"); + printf(" Previous Menu ----------------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} + +/** + * @brief Get FW information. + * @param SlotNumber slot identification + * @retval HAL Status. + */ +static void SE_USER_CODE_GetFwInfo(uint32_t SlotNumber) +{ + SE_ErrorStatus se_retCode = SE_ERROR; + SE_StatusTypeDef se_Status = SE_KO; + SE_APP_ActiveFwInfo_t sl_FwInfo; + + memset(&sl_FwInfo, 0xFF, sizeof(SE_APP_ActiveFwInfo_t)); + + + + /* Get FW info */ + se_retCode = SE_APP_GetActiveFwInfo(&se_Status, SlotNumber, &sl_FwInfo); + + if ((SE_SUCCESS == se_retCode) && (SE_OK == se_Status)) + { + /* Print the result */ + printf("Firmware Info:\r\n"); + printf("\tActiveFwVersion: %d\r\n", sl_FwInfo.ActiveFwVersion); + printf("\tActiveFwSize: %d bytes\r\n", sl_FwInfo.ActiveFwSize); + } + else + { + /* Failure */ + printf(" -- !!Operation failed!! \r\n\n"); + } + +} + + +/** + * @} + */ + +/** @addtogroup SE_USER_CODE_Exported_Functions + * @{ + */ + +/** + * @brief Run get firmware info menu. + * @param None + * @retval HAL Status. + */ +void SE_USER_CODE_RunMenu(void) +{ + uint8_t key = 0U; + uint32_t exit = 0U; + uint32_t slot_number = 0U; + + /*Print Main Menu message*/ + SE_USER_CODE_PrintMenu(); + + while (exit == 0U) + { + key = 0U; + slot_number = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload + register */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + slot_number = SLOT_ACTIVE_1; + if (SlotStartAdd[slot_number] == 0U) + { + printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); + } + else + { + SE_USER_CODE_GetFwInfo(slot_number); + } + break; + case 'x' : + exit = 1U; + break; + default: + printf("Invalid Number !\r"); + break; + } + + if (exit != 1U) + { + if (SlotStartAdd[slot_number] == 0U) + { + printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); + } + else + { + SE_USER_CODE_GetFwInfo(slot_number); + } + + /*Print Main Menu message*/ + SE_USER_CODE_PrintMenu(); + } + } + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/stm32wlxx_it.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/stm32wlxx_it.c new file mode 100644 index 00000000..2f44492a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/stm32wlxx_it.c @@ -0,0 +1,220 @@ +/** + ****************************************************************************** + * @file stm32wlxx_it.c + * @author MCD Application Team + * @brief Main Interrupt Service Routines. + * This file provides template for all exceptions handler and + * peripherals interrupt service routine. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32wlxx_it.h" +#include "test_protections.h" + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup USER_APP_COMMON Common + * @{ + */ +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +RTC_HandleTypeDef RtcHandle; +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + * @param None + * @retval None + */ +void NMI_Handler(void) +{ + /* Go to infinite loop when NMI exception occurs */ + while (1) + { + printf("NMI exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Hard Fault exception. + * @param None + * @retval None + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + printf("Hard Fault exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Memory Manage exception. + * @param None + * @retval None + */ +void MemManage_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + printf("Memory Manage exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + printf("Bus Fault exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + printf("Usage Fault exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +void SVC_Handler(void) +{ +} + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +void PendSV_Handler(void) +{ +} + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +void SysTick_Handler(void) +{ + HAL_IncTick(); +} + +/******************************************************************************/ +/* STM32WLxx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32wlxx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles Flash operation error interrupt request. + * @param None + * @retval None + */ +void FLASH_IRQHandler(void) +{ + HAL_FLASH_IRQHandler(); +} + +/** + * @brief This function handles Tamper interrupt request. + * @param None + * @retval None + */ +void TAMP_STAMP_LSECSS_SSRU_IRQHandler() +{ + /* Store in the handle the Internal Tamper enabled */ + SET_BIT(RtcHandle.IsEnabled.TampFeatures, RTC_TAMPER_ID); + + RtcHandle.Instance = RTC; + HAL_RTCEx_TamperIRQHandler(&RtcHandle); +} + +void BUTTON_IRQHANDLER(void) +{ + HAL_GPIO_EXTI_IRQHandler(BUTTON_EXTI_LINE); +} + +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + if (GPIO_Pin == BUTTON_EXTI_LINE) + { + printf("\r\nUser IRQ Handler: User Button pressed\r\n"); + } +} + +/** + * @brief This function handles PPP interrupt request. + * @param None + * @retval None + */ +/*void PPP_IRQHandler(void) +{ +}*/ + + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/system_stm32wlxx.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/system_stm32wlxx.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/system_stm32wlxx.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/system_stm32wlxx.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/test_protections.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/test_protections.c new file mode 100644 index 00000000..38b51f1a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/test_protections.c @@ -0,0 +1,458 @@ +/** + ****************************************************************************** + * @file test_protections.c + * @author MCD Application Team + * @brief Test Protections module. + * This file provides set of firmware functions to manage Test Protections + * functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define TEST_PROTECTIONS_C + +/* Includes ------------------------------------------------------------------*/ +#include +#include "test_protections.h" +#include "se_def.h" +#include "se_interface_application.h" +#include "com.h" +#include "common.h" +#include "flash_if.h" +#include "sfu_fwimg_regions.h" /* required for corruption tests (a real user application should NOT need this file) */ +#if defined(__ARMCC_VERSION) +#include "mapping_sbsfu.h" +#elif defined (__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __ARMCC_VERSION */ +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup TEST_PROTECTIONS Test protections + * @{ + */ + +/** @defgroup TEST_PROTECTIONS_Private_Defines Private Defines + * @{ + */ + +/** + * @brief Isolated enclave Test. + */ +/*!< Address used to test SE CODE protection*/ +#define TEST_PROTECTIONS_SE_ISOLATED_CODE_FLASH_ADDRESS ((uint32_t) SE_CALLGATE_REGION_ROM_START) +/*!< Address used to test SE VDATA protection*/ +#define TEST_PROTECTIONS_SE_ISOLATED_VDATA_SRAM_ADDRESS ((uint32_t) SE_REGION_RAM_START) + +/** + * @brief WRP Test. + */ +/*!< Address used to test WRP protection */ +#define TEST_PROTECTIONS_WRP_FLASH_ADDRESS ((uint32_t) (KMS_DATASTORAGE_START - 0x1000)) +/*!< WRP Test Size */ +#define TEST_PROTECTIONS_WRP_FLASH_SIZE ((uint32_t)0x800U) + +/** + * @brief IWDG Test. + */ +/*!< IWDG Test delay in ms (it has to be greater than what used in SB)*/ +#define TEST_PROTECTIONS_IWDG_DELAY ((uint32_t)10000U) + +/** + * @brief TAMPER Test. + */ +#define TEST_PROTECTIONS_TAMPER_DELAY ((uint32_t)10U) /*!< TAMPER Test delay in s */ + +/** + * @brief CORRUPT_IMAGE Test. + */ +/*!< CORRUPT_IMAGE Test: address where data will be corrupted: address of active slot + offset */ +#define TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(A) ((uint32_t)(SlotStartAdd[A] \ + +SFU_IMG_IMAGE_OFFSET)) +/*!< CORRUPT_IMAGE Test: size of data to be corrupted */ +#define TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE ((uint32_t)32U) + +/** @defgroup TEST_PROTECTIONS_Private_Variables Private Variables + * @{ + */ +static uint8_t uRead_WRP[TEST_PROTECTIONS_WRP_FLASH_SIZE]; /*!< RTC handler used for TAMPER Test */ +static uint32_t m_uTamperEvent = 0U; /*!< Tamper Event */ + +/** @defgroup TEST_PROTECTIONS_Private_Functions Private Functions + * @{ + */ +static void TEST_PROTECTIONS_RunWRP(void); +static void TEST_PROTECTIONS_RunTAMPER(void); +static void TEST_PROTECTIONS_RunIWDG(void); +static void TEST_PROTECTIONS_CORRUPT_RunMenu(void); +static void TEST_PROTECTIONS_PrintTestingMenu(void); +/** + * @} + */ + + + + +/** @defgroup TEST_PROTECTIONS_Exported_Functions Exported Functions + * @{ + */ + +/** @defgroup TEST_PROTECTIONS_Control_Functions Control Functions + * @{ + */ + +/** + * @brief Display the TEST Main Menu choices on HyperTerminal + * @param None. + * @retval None. + */ +void TEST_PROTECTIONS_RunMenu(void) +{ + uint8_t key = 0U; + uint8_t exit = 0U; + + /* Print Main Menu message */ + TEST_PROTECTIONS_PrintTestingMenu(); + + while (exit == 0U) + { + key = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the + reload register*/ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + TEST_PROTECTIONS_CORRUPT_RunMenu(); + break; + case '2' : + TEST_PROTECTIONS_RunWRP(); + break; + case '3' : + TEST_PROTECTIONS_RunIWDG(); + break; + case '4' : + TEST_PROTECTIONS_RunTAMPER(); + break; + case 'x' : + exit = 1U; + break; + + default: + printf("Invalid Number !\r"); + break; + } + /*Print Main Menu message*/ + TEST_PROTECTIONS_PrintTestingMenu(); + } + } +} + + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup TEST_PROTECTIONS_Private_Functions + * @{ + */ + +/** + * @brief Display the TEST Main Menu choices on HyperTerminal + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_PrintTestingMenu(void) +{ + printf("\r\n=================== Test Menu ============================\r\n\n"); + printf(" Test : CORRUPT ACTIVE IMAGE --------------------------- 1\r\n\n"); + printf(" Test Protection: WRP ---------------------------------- 2\r\n\n"); + printf(" Test Protection: IWDG --------------------------------- 3\r\n\n"); + printf(" Test Protection: TAMPER ------------------------------- 4\r\n\n"); + printf(" Previous Menu ----------------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} + + +/** + * @brief TEST Run WRP + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunWRP(void) +{ + uint32_t i = 0U; + uint32_t address = 0U; + + printf("\r\n====== Test Protection: WRP ===========================\r\n\n"); + + address = TEST_PROTECTIONS_WRP_FLASH_ADDRESS; + + /* 1 - Read Page to be used for restoring*/ + printf(" -- Reading 0x%x bytes at address: 0x%x (for backup)\r\n\n", TEST_PROTECTIONS_WRP_FLASH_SIZE, + TEST_PROTECTIONS_WRP_FLASH_ADDRESS); + + for (i = 0U; i < TEST_PROTECTIONS_WRP_FLASH_SIZE; i++) + { + uRead_WRP[i] = *((uint8_t *)(address + i)); + } + + /* 2 - Erasing page */ + printf(" -- Erasing 0x%x bytes at address: 0x%x\r\n\n", TEST_PROTECTIONS_WRP_FLASH_SIZE, + TEST_PROTECTIONS_WRP_FLASH_ADDRESS); + + /* Check that it is not allowed to erase this page */ + if (FLASH_If_Erase_Size((void *)address, TEST_PROTECTIONS_WRP_FLASH_SIZE) != HAL_OK) + { + /* Error returned during programmation. */ + /* Check that WRPERR flag is set */ + if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) != 0U) + { + printf("-- !! HAL_FLASH_ERROR_WRP: FLASH Write protected error flag !!\r\n\n"); + } + } + else + { + /* 3 - Writing Data previously read*/ + if (FLASH_If_Write((void *)address, uRead_WRP, TEST_PROTECTIONS_WRP_FLASH_SIZE) != HAL_OK) + { + /* Error returned during programmation. */ + printf("-- !! HAL_FLASH_ERROR: FLASH Write error\r\n\n"); + + /* Check that WRPERR flag is set */ + if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) != 0U) + { + printf("-- !! HAL_FLASH_ERROR_WRP: FLASH Write protected error flag !!\r\n\n"); + } + } + else + { + printf(" -- Written successfully at address: 0x%x\r\n\n", TEST_PROTECTIONS_WRP_FLASH_ADDRESS); + + /*No Errors detected means WRP was not enabled*/ + printf(" -- !! WRP protection is NOT ENABLED !!\r\n\n"); + } + } +} + +/** + * @brief TEST Run CORRUPT_IMAGE + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunCORRUPT(uint32_t slot_number) +{ + HAL_StatusTypeDef ret = HAL_ERROR; + uint8_t pattern[TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE] = {0}; + + /* On this series, there is no MPU to disable to allow flash corruption. */ + + /* Erase first sector of active slot */ + printf(" -- Erasing 0x%x bytes at address: 0x%x\r\n", TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE, + TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(slot_number)); + printf(" -- At next boot Signature Verification will fail. Download a new FW to restore FW image !!\r\n\n"); + + /* On this series, the memory corruption is performed by writing again the flash (but not header). + The header is preserved for anti-rollback check. */ + ret = FLASH_If_Write((void *)(TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(slot_number)), (void *) &pattern, + TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE); + + /* This code may not be reached, due to the memory corruption performed. + In this case, the execution will probably trig hard fault exception (while (1)), + then watchdog reset. */ + if (ret == HAL_OK) + { + NVIC_SystemReset(); + } + else + { + printf("-- !! HAL_FLASH_ERROR_CORRUPT_IMAGE: erasing failure ...\r\n\n"); + } +} + +/** + * @brief Display the corruption menu + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_CORRUPT_PrintMenu(void) +{ + printf("\r\n============ Test: CORRUPT ACTIVE IMAGE ============\r\n\n"); + printf(" Corrupt image from SLOT_ACTIVE_1 ---------------------- 1\r\n\n"); + printf(" Previous Menu ----------------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} + +/** + * @brief Run get firmware info menu. + * @param None + * @retval HAL Status. + */ +static void TEST_PROTECTIONS_CORRUPT_RunMenu(void) +{ + uint8_t key = 0U; + uint32_t exit = 0U; + uint32_t slot_number = 0U; + + /*Print Main Menu message*/ + TEST_PROTECTIONS_CORRUPT_PrintMenu(); + + while (exit == 0U) + { + key = 0U; + slot_number = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload + register */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + slot_number = SLOT_ACTIVE_1; + break; + case 'x' : + exit = 1U; + break; + default: + printf("Invalid Number !\r"); + break; + } + + if (exit != 1U) + { + if (SlotStartAdd[slot_number] == 0U) + { + printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); + } + else + { + TEST_PROTECTIONS_RunCORRUPT(slot_number); + } + + /*Print Main Menu message*/ + TEST_PROTECTIONS_CORRUPT_PrintMenu(); + } + } + } +} + + +/** + * @brief TEST Run TAMPER + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunTAMPER(void) +{ + uint32_t i = 0U; + m_uTamperEvent = 0U; + + printf("\r\n====== Test Protection: TAMPER ========================\r\n\n"); + /* Print instructions*/ + printf(" -- Pull PC13 (CN7.23) to GND \r\n\n"); + printf(" -- -- Note: sometimes it may be enough to put your finger close to PC13 (CN7.23)\r\n\n"); + printf(" -- Should reset if TAMPER is enabled. \r\n\n"); + printf(" Waiting for 10 seconds...\r\n\n") ; + + /* #2 - Wait 10 seconds*/ + while ((i < TEST_PROTECTIONS_TAMPER_DELAY) && (m_uTamperEvent == 0U)) + { + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload register + */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + HAL_Delay(1000U); + i++; + } + if (m_uTamperEvent == 0U) + { + printf("\r\n\n -- Waited 10 seconds, if you have connected TAMPER pin to GND it means TAMPER protection "); + printf("is NOT ENABLED !! \r\n\n"); + } + else + { + printf("\r\n\n -- TAMPER Event detected!!\r\n\n -- System reset requested!!!\r\n\n"); + NVIC_SystemReset(); + } +} + +/** + * @brief TEST Run IWDG + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunIWDG(void) +{ + printf("\r\n====== Test Protection: IWDG ===========================\r\n\n"); + + /* Wait for TEST_PROTECTIONS_IWDG_DELAY*/ + printf(" -- Waiting %d (ms). Should reset if IWDG is enabled. \r\n\n", TEST_PROTECTIONS_IWDG_DELAY); + + HAL_Delay(TEST_PROTECTIONS_IWDG_DELAY); + + /* No Reset means IWDG was not enabled*/ + printf(" -- !! IWDG protection is NOT ENABLED !!\r\n\n"); +} + +/** + * @} + */ + +/** @defgroup TEST_PROTECTIONS_Callback_Functions Callback Functions + * @{ + */ + +/** + * @brief Implement the Cube_Hal Callback generated on the Tamper IRQ. + * @param None + * @retval None + */ +void CALLBACK_Antitamper(void) +{ + /*Set tamper event variable*/ + m_uTamperEvent = 1U; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app.c new file mode 100644 index 00000000..50a2847b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app.c @@ -0,0 +1,207 @@ +/** + ****************************************************************************** + * @file tkms_app.c + * @author MCD Application Team + * @brief tKMS application examples module. + * This file provides examples of KMS API usages. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" + + +/* Private variables ---------------------------------------------------------*/ +extern void KMS_UPDATE_StartLocalUpdate(void); /* Function to perform Ymodem download of blob image to import */ + +static void tkms_app_print_menu(void) +{ + (void)printf("\r\n======================= tKMS Examples Menu ===========================\r\n\n"); + (void)printf(" (*) Requires execution of 'Import Blob' test (3) prior to execute this one\r\n\n"); + (void)printf(" TKMS - Test All (*) --------------------- 0\r\n\n"); + (void)printf(" TKMS - Tests AES-GCM Embedded key --------------------- 1\r\n\n"); + (void)printf(" TKMS - Tests AES-CBC Embedded key --------------------- 2\r\n\n"); + (void)printf(" TKMS - Import blob --------------------- 3\r\n\n"); + (void)printf(" TKMS - Tests RSA Static key (*) --------------------- 4\r\n\n"); + (void)printf(" TKMS - Tests Derive Static key (*) --------------------- 5\r\n\n"); + (void)printf(" TKMS - Tests key finding --------------------- 6\r\n\n"); + (void)printf(" Exit tKMS Examples Menu --------------------- x\r\n\n"); +} + +void tkms_app_menu(void) +{ + uint8_t key; + uint8_t exit = 0U; + CK_RV ret_status; + uint8_t tests_executed; /* Tests executed count */ + uint8_t tests_success; /* Tests success count */ + uint8_t clear_buffer[128] = "STM32 Key Management Services - Example buffer"; /* Clear text test buffer */ + + /* Initialize tKMS for subsequent usage */ + ret_status = C_Initialize(NULL); + if (ret_status != CKR_OK) + { + (void)printf("tKMS initialization failed\r\n"); + exit = 1; + } + else + { + tkms_app_print_menu(); + } + + while (exit == 0U) /* Till user request to exit this menu, loop on it */ + { + key = 0U; + + INVOKE_SCHEDULE_NEEDS(); + + /* Clean the user input path */ + (void)COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) /* User pressed key */ + { + case '0' : + /* + * Execute the whole supported tests in sequence + * For each test: + * - call INVOKE_SCHEDULE_NEEDS to rewarm WDG + * - check results and report test status + * At the end, global result is provided + */ + tests_executed = 0U; + tests_success = 0U; + ret_status = tkms_app_encrypt_decrypt_aes_gcm(sizeof(clear_buffer), clear_buffer); + (void)printf("AES GCM test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_encrypt_decrypt_aes_cbc(sizeof(clear_buffer), clear_buffer); + (void)printf("AES CBC test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_sign_verify_rsa(sizeof(clear_buffer), clear_buffer); + (void)printf("RSA test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_derive_key(sizeof(clear_buffer), clear_buffer); + (void)printf("Derive key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_find(); + (void)printf("Find key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + /* Report final status */ + if (tests_success == tests_executed) + { + (void)printf("CUMULATIVE RESULT: ALL TESTS PASSED\r\n"); + } + else + { + (void)printf("CUMULATIVE RESULT: %d/%d success\r\n", tests_success, tests_executed); + } + tkms_app_print_menu(); + break; + + /* 1 = TKMS - Tests AES-GCM Embedded key */ + case '1' : + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_encrypt_decrypt_aes_gcm(sizeof(clear_buffer), clear_buffer); + (void)printf("AES GCM test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 2 = Tests AES-CBC Embedded key */ + case '2' : + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_encrypt_decrypt_aes_cbc(sizeof(clear_buffer), clear_buffer); + (void)printf("AES CBC test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 3 = Import Blob */ + case '3': + INVOKE_SCHEDULE_NEEDS(); + KMS_UPDATE_StartLocalUpdate(); + tkms_app_print_menu(); + break; + /* 4 = Tests RSA Static key (requires blob import) */ + case '4' : + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_sign_verify_rsa(sizeof(clear_buffer), clear_buffer); + (void)printf("RSA test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 5 = Tests Key derivation (requires blob import) */ + case '5': + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_derive_key(sizeof(clear_buffer), clear_buffer); + (void)printf("Derive key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 6 = Tests Key finding */ + case '6': + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_find(); + (void)printf("Find key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + case 'x': + exit = 1; + break; + + default: + (void)printf("Invalid Number !\r"); + tkms_app_print_menu(); + break; + } + } + } + + /* Finalize tKMS since no more in use */ + ret_status = C_Finalize(NULL); + if (ret_status != CKR_OK) + { + (void)printf("tKMS finalization failed\r\n"); + } +} + +/* + * Utilities to format buffer in string for display in traces + */ +void tkms_buff2str(uint8_t *pbuff, uint8_t *pstr, uint32_t length) +{ + uint8_t ascii[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + uint8_t *ptmp = pstr; + uint8_t *ptmp2 = pbuff; + for (uint32_t i = 0UL; i < length; i += 1UL) + { + *ptmp = ascii[*ptmp2 >> 4]; + ptmp++; + *ptmp = ascii[*ptmp2 & 0x0FUL]; + ptmp++; + ptmp2++; + } + *ptmp = 0U; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_derive_key.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_derive_key.c new file mode 100644 index 00000000..6d6e7ebb --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_derive_key.c @@ -0,0 +1,210 @@ +/** + ****************************************************************************** + * @file tkms_app_derive_key.c + * @author MCD Application Team + * @brief tKMS application examples module. + * This file provides examples of KMS API usage to derivate a key + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines -----------------------------------------------------------*/ +#define EC_POINT_MAX_LEN (3U + (2U * 32U)) /* EC Point Max Length : X962 header + DER header + + NIST-P256 *2 - > (0x04|LEN|0x04|X|Y) */ +#define DH_SECRET_X_MAX_LEN (32U) /* DH Secret X Max Length */ + +/* Private structures --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static uint8_t a_string[1024] = {0}; + + +/** + * @brief Key derivation + * This example is showing how to use key derivation to create + * a specific session key. + * @note + * Key derivation shared information between emitter and receiver + * - Secret derivation Key: stored in KMS under + * KMS_KEY_AES128_DERIVABLE_OBJECT_HANDLE object handle + * - Session key variation: transmitted or calculated by both emitter & receiver + * @param length Length of the clear text for encryption/decryption tests + * @param pClearMessage Clear text for encryption/decryption tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_derive_key(uint32_t length, uint8_t *pClearMessage) +{ + uint8_t encrypted_message[256] __attribute__((aligned(8))) = {0}; + uint8_t decrypted_message[256] __attribute__((aligned(8))) = {0}; + /* Generated key template definition */ + CK_ULONG DeriveKey_template_class = CKO_SECRET_KEY; + CK_ULONG DeriveKey_template_destroyable = CK_TRUE; + CK_ULONG DeriveKey_template_encrypt = CK_TRUE; + CK_ULONG DeriveKey_template_decrypt = CK_TRUE; + CK_ULONG DeriveKey_template_extract = CK_TRUE; + CK_ATTRIBUTE DeriveKey_template[] = + { + {CKA_CLASS, (CK_VOID_PTR) &DeriveKey_template_class, sizeof(CK_ULONG)}, + {CKA_DESTROYABLE, (CK_VOID_PTR) &DeriveKey_template_destroyable, sizeof(CK_ULONG)}, + {CKA_ENCRYPT, (CK_VOID_PTR) &DeriveKey_template_encrypt, sizeof(CK_ULONG)}, + {CKA_DECRYPT, (CK_VOID_PTR) &DeriveKey_template_decrypt, sizeof(CK_ULONG)}, + {CKA_EXTRACTABLE, (CK_VOID_PTR) &DeriveKey_template_extract, sizeof(CK_ULONG)} + }; + /* Template to retrieve generate key value */ + CK_ATTRIBUTE GetKey_template[] = {{CKA_VALUE, (CK_VOID_PTR) &DeriveKey_template_class, 32UL}}; + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + /* Key derivation */ + uint8_t session_variant[32] = "My session variation 0122004578"; + CK_MECHANISM mech = {CKM_AES_ECB_ENCRYPT_DATA, session_variant, 32}; + CK_OBJECT_HANDLE derivedKeyHdle = 0UL; + uint8_t derivedKey[32] = {0}; + /* AES encryption / decryption */ + uint32_t encrypted_length = 0UL; + uint32_t decrypted_length = 0UL; + uint8_t cbc_iv[16] = ">CBC VECTOR "; + CK_MECHANISM aes_cbc_mechanism = { CKM_AES_CBC, (CK_VOID_PTR)cbc_iv, sizeof(cbc_iv) }; + uint8_t tag[16] = {0}; + uint32_t tag_lenth; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Derive key with pass phrase */ + if (rv == CKR_OK) + { + rv = C_DeriveKey(session, &(mech), (CK_OBJECT_HANDLE)KMS_KEY_AES128_DERIVABLE_OBJECT_HANDLE, + &DeriveKey_template[0], sizeof(DeriveKey_template) / sizeof(CK_ATTRIBUTE), &derivedKeyHdle); + } + + /* Get derived key to display */ + if (rv == CKR_OK) + { + GetKey_template[0].pValue = derivedKey; + rv = C_GetAttributeValue(session, derivedKeyHdle, &(GetKey_template[0]), sizeof(GetKey_template) / + sizeof(CK_ATTRIBUTE)); + } + if (rv == CKR_OK) + { + (void)printf("--- Derivating key --------------------------------------------\r\n"); + (void)printf("--- AES ECB\r\n"); + (void)printf("--- Pass phrase [%s]\r\n", session_variant); + tkms_buff2str(derivedKey, a_string, 32); + (void)printf("--- Derived key [%s]\r\n", a_string); + } + + /* Encryption --------------------------------------------------------------*/ + (void)printf("--- Encrypting --------------------------------------------------\r\n"); + (void)printf("--- AES CBC\r\n"); + (void)printf("--- IV [%s]\r\n", cbc_iv); + (void)printf("--- Message [%s]\r\n", pClearMessage); + tkms_buff2str(pClearMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to encrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_EncryptInit(session, &aes_cbc_mechanism, derivedKeyHdle); + } + + /* Encrypt clear message */ + if (rv == CKR_OK) + { + encrypted_length = sizeof(encrypted_message); + rv = C_EncryptUpdate(session, pClearMessage, length, + encrypted_message, &encrypted_length); + } + + /* Finalize message encryption */ + if (rv == CKR_OK) + { + tag_lenth = sizeof(tag); + rv = C_EncryptFinal(session, &tag[0], &tag_lenth); + } + + (void)printf("--- Encrypted ---------------------------------------------------\r\n"); + tkms_buff2str(encrypted_message, a_string, encrypted_length); + (void)printf("--- Message [0x%s]\r\n", a_string); + + /* Decryption --------------------------------------------------------------*/ + + /* Configure session to decrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_DecryptInit(session, &aes_cbc_mechanism, derivedKeyHdle); + } + + /* Decrypt encrypted message */ + if (rv == CKR_OK) + { + decrypted_length = sizeof(decrypted_message); + rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, + decrypted_message, &decrypted_length); + } + + /* Finalize message decryption */ + if (rv == CKR_OK) + { + tag_lenth = sizeof(tag); + rv = C_DecryptFinal(session, &tag[0], &tag_lenth); + } + (void)printf("--- Decrypted ---------------------------------------------------\r\n"); + (void)printf("--- Message [%s]\r\n", decrypted_message); + tkms_buff2str(decrypted_message, a_string, decrypted_length); + (void)printf("--- [0x%s]\r\n", a_string); + + /* Compare decrypted message with clear one */ + if (rv == CKR_OK) + { + if (memcmp(pClearMessage, decrypted_message, length) != 0) + { + (void)printf("XXX Decrypted message differs\r\n"); + rv = CKR_FUNCTION_FAILED; + } + else + { + (void)printf(">>> Decrypted message is same\r\n"); + } + } + + /* Remove key once no more needed */ + if (rv == CKR_OK) + { + rv = C_DestroyObject(session, derivedKeyHdle); + } + + /* Verify key is no more usable */ + if (rv == CKR_OK) + { + if (C_EncryptInit(session, &aes_cbc_mechanism, derivedKeyHdle) == CKR_OK) + { + rv = CKR_FUNCTION_FAILED; + } + } + + /* Close sessions */ + (void)C_CloseSession(session); + + return rv; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c new file mode 100644 index 00000000..5692f717 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c @@ -0,0 +1,293 @@ +/** + ****************************************************************************** + * @file tkms_app_encrypt_decrypt.c + * @author MCD Application Team + * @brief KMS application examples module. + * This file provides examples of KMS API usage to encrypt & decrypt + * messages. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines ---------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static uint8_t a_string[1024] = {0}; +static uint8_t encrypted_message[256] __attribute__((aligned(8))) = {0}; +static uint8_t decrypted_message[256] __attribute__((aligned(8))) = {0}; + +/** + * @brief AES GCM 128 Bits + * This example is showing how to use AES GCM encryption/decryption to + * authenticate and protect a message. + * @note + * Shared information between emitter and receiver + * - Secret encryption/decryption Key: stored in KMS under + * KMS_KEY_AES128_OBJECT_HANDLE object handle + * - Encrypted message: transmitted from emitter to sender + * - Initialization Vector: transmitted from emitter to sender + * - Message Header: transmitted from emitter to sender + * - Authentication Tag: transmitted from emitter to sender + * (calculated during encryption, verified during decryption) + * @param length Length of the clear text for encryption/decryption tests + * @param pClearMessage Clear text for encryption/decryption tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_encrypt_decrypt_aes_gcm(uint32_t length, uint8_t *pClearMessage) +{ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t encrypted_length = 0UL; + uint32_t decrypted_length = 0UL; + uint8_t tag[16] = {0}; /* 128 bits tag size */ + uint32_t tag_lenth = 0UL; + + /* AES GCM Configuration variables */ + uint8_t gcm_iv[12] = ">GCM VECTOR"; + uint8_t gcm_header[16] = ">AES GCM Header"; + /* Prepare GCM mechanism */ + CK_GCM_PARAMS gcm_params = + { + (CK_BYTE *)gcm_iv, + sizeof(gcm_iv), + (CK_BYTE_PTR)gcm_header, + sizeof(gcm_header), + 128 /* Tag length in Bits */ + }; + CK_MECHANISM aes_gcm_mechanism = { CKM_AES_GCM, (CK_VOID_PTR *)(uint32_t) &gcm_params, sizeof(gcm_params) }; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Encryption --------------------------------------------------------------*/ + (void)printf("--- Encrypting --------------------------------------------------\r\n"); + (void)printf("--- AES GCM\r\n"); + (void)printf("--- IV [%s]\r\n", gcm_iv); + (void)printf("--- Header [%s]\r\n", gcm_header); + (void)printf("--- Message [%s]\r\n", pClearMessage); + tkms_buff2str(pClearMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to encrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_EncryptInit(session, &aes_gcm_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES128_OBJECT_HANDLE); + } + + /* Encrypt clear message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + encrypted_length = sizeof(encrypted_message); + rv = C_EncryptUpdate(session, pClearMessage, length, + encrypted_message, &encrypted_length); + } + + /* Finalize message encryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_EncryptFinal(session, &tag[0], &tag_lenth); + } + + (void)printf("--- Encrypted ---------------------------------------------------\r\n"); + tkms_buff2str(encrypted_message, a_string, encrypted_length); + (void)printf("--- Message [0x%s]\r\n", a_string); + tkms_buff2str(tag, a_string, tag_lenth); + (void)printf("--- Tag [0x%s]\r\n", a_string); + + /* Decryption --------------------------------------------------------------*/ + + /* Configure session to decrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_DecryptInit(session, &aes_gcm_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES128_OBJECT_HANDLE); + } + + /* Decrypt encrypted message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + decrypted_length = sizeof(decrypted_message); + rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, + decrypted_message, &decrypted_length); + } + + /* Finalize message decryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_DecryptFinal(session, &tag[0], &tag_lenth); + } + (void)printf("--- Decrypted ---------------------------------------------------\r\n"); + (void)printf("--- Message [%s]\r\n", decrypted_message); + tkms_buff2str(decrypted_message, a_string, decrypted_length); + (void)printf("--- [0x%s]\r\n", a_string); + + if (rv == CKR_OK) + { + (void)printf(">>> Decrypted message authenticated\r\n"); + } + else + { + (void)printf("XXX Decrypted message not authenticated\r\n"); + } + + /* Compare decrypted message with clear one */ + if (rv == CKR_OK) /* Tag verification done into C_DecryptFinal, thus tag check reflected into rv */ + { + if (memcmp(pClearMessage, decrypted_message, length) != 0) + { + (void)printf("XXX Decrypted message differs\r\n"); + rv = CKR_FUNCTION_FAILED; + } + else + { + (void)printf(">>> Decrypted message is same\r\n"); + } + } + + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + +/** + * @brief AES CBC 256 Bits + * This example is showing how to use AES CBC encryption/decryption to + * protect a message. + * @note + * CBC shared information between emitter and receiver + * - Secret encryption/decryption Key: stored in KMS under + * KMS_KEY_AESC256_OBJECT_HANDLE object handle + * - Encrypted message: transmitted from emitter to sender + * - Initialization Vector: transmitted from emitter to sender + * @param length Length of the clear text for encryption/decryption tests + * @param pClearMessage Clear text for encryption/decryption tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_encrypt_decrypt_aes_cbc(uint32_t length, uint8_t *pClearMessage) +{ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t encrypted_length = 0UL; + uint32_t decrypted_length = 0UL; + uint8_t tag[16] = {0}; + uint32_t tag_lenth; + + /* AES CBC Configuration variables */ + uint8_t cbc_iv[16] = ">CBC VECTOR "; + CK_MECHANISM aes_cbc_mechanism = { CKM_AES_CBC, (CK_VOID_PTR)(uint32_t)cbc_iv, sizeof(cbc_iv) }; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Encryption --------------------------------------------------------------*/ + (void)printf("--- Encrypting --------------------------------------------------\r\n"); + (void)printf("--- AES CBC\r\n"); + (void)printf("--- IV [%s]\r\n", cbc_iv); + (void)printf("--- Message [%s]\r\n", pClearMessage); + tkms_buff2str(pClearMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to encrypt message in AES CBC with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_EncryptInit(session, &aes_cbc_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES256_OBJECT_HANDLE); + } + + /* Encrypt clear message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + encrypted_length = sizeof(encrypted_message); + rv = C_EncryptUpdate(session, pClearMessage, length, + encrypted_message, &encrypted_length); + } + + /* Finalize message encryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_EncryptFinal(session, &tag[0], &tag_lenth); + } + + (void)printf("--- Encrypted ---------------------------------------------------\r\n"); + tkms_buff2str(encrypted_message, a_string, encrypted_length); + (void)printf("--- Message [0x%s]\r\n", a_string); + + /* Decryption --------------------------------------------------------------*/ + + /* Configure session to decrypt message in AES CBC with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_DecryptInit(session, &aes_cbc_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES256_OBJECT_HANDLE); + } + + /* Decrypt encrypted message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + decrypted_length = sizeof(decrypted_message); + rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, + decrypted_message, &decrypted_length); + } + + /* Finalize message decryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_DecryptFinal(session, &tag[0], &tag_lenth); /* In case of AES CBC, no tag comparison is done */ + } + (void)printf("--- Decrypted ---------------------------------------------------\r\n"); + (void)printf("--- Message [%s]\r\n", decrypted_message); + tkms_buff2str(decrypted_message, a_string, decrypted_length); + (void)printf("--- [0x%s]\r\n", a_string); + + /* Compare decrypted message with clear one */ + if (rv == CKR_OK) + { + if (memcmp(pClearMessage, decrypted_message, length) != 0) + { + (void)printf("XXX Decrypted message differs\r\n"); + rv = CKR_FUNCTION_FAILED; + } + else + { + (void)printf(">>> Decrypted message is same\r\n"); + } + } + + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_find.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_find.c new file mode 100644 index 00000000..6241319d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_find.c @@ -0,0 +1,96 @@ +/** + ****************************************************************************** + * @file tkms_app_find.c + * @author MCD Application Team + * @brief KMS application examples module. + * This file provides examples of KMS API usage to find + * objects. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines -----------------------------------------------------------*/ +#define TEST_KEY_AES128 "USERCRYP128" +#define TEST_KEY_AES256 "USERCRYP256" +/* Private variables ---------------------------------------------------------*/ + +/** + * @brief Object search + * This example is showing how to find an object. + * @param None + * @retval CK_RV return value. + */ +CK_RV tkms_app_find(void) +{ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_ATTRIBUTE object_template; + CK_OBJECT_HANDLE object_handle; + CK_ULONG count; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Fill in the template with the attribute to retrieve the specific key + (CKA_LABEL is used to refer to a specific object) */ + object_template.type = CKA_LABEL; + object_template.pValue = TEST_KEY_AES128; + object_template.ulValueLen = sizeof(TEST_KEY_AES128); + + (void)printf("--- Find Object -----------------------------------------------------\r\n"); + (void)printf("--- Label [%s]\r\n", (uint8_t *)object_template.pValue); + + /* Find Objects Init : template of the object to retrieve is passed to KMS */ + if (rv == CKR_OK) + { + rv = C_FindObjectsInit(session, (CK_ATTRIBUTE_PTR)&object_template, 1); + } + + /* Find Objects : Find object corresponding to the template specified in FindObjectsInit */ + if (rv == CKR_OK) + { + count = 1; + rv = C_FindObjects(session, &object_handle, 1, &count); + } + + /* Find Objects Final: Finalize the operation */ + if (rv == CKR_OK) + { + rv = C_FindObjectsFinal(session); + } + + if (rv == CKR_OK) + { + (void)printf("--- Object Found ------------------------------------------------\r\n"); + (void)printf("--- Object Handle [%d]\r\n", object_handle); + } + else + { + printf("--- Object Not Found --------------------------------------------\r\n"); + } + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_sign_verify.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_sign_verify.c new file mode 100644 index 00000000..c4a0c8aa --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/tkms_app_sign_verify.c @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * @file tkms_app_sign_verify.c + * @author MCD Application Team + * @brief KMS application examples module. + * This file provides examples of KMS API usage to sign & verify + * messages. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines -----------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static uint8_t a_string[1024] = {0}; +static uint8_t signature[2048 / 8] __attribute__((aligned(8))) = {0}; + + +/** + * @brief RSA 1024 Bits + * This example is showing how to use RSA signature to + * authenticate a message. + * @note + * RSA shared information between emitter and receiver + * - Secret signature/verification Key: stored in KMS under + * KMS_KEY_RSA2048_OBJECT_HANDLE object handle + * - Message to authenticate: transmitted from emitter to sender + * - Signature: transmitted from emitter to sender + * (calculated by emitter, verified by receiver) + * @param length Length of the clear text for signature/verification tests + * @param pMessage Clear text for signature/verification tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_sign_verify_rsa(uint32_t length, uint8_t *pMessage) +{ + + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t signature_length = 0UL; + + /* Prepare RSA mechanism */ + CK_MECHANISM rsa_mechanism = { CKM_SHA256_RSA_PKCS, (CK_VOID_PTR *) NULL, 0}; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Signature --------------------------------------------------------------*/ + (void)printf("--- Signing -----------------------------------------------------\r\n"); + (void)printf("--- RSA 1024 bits\r\n"); + (void)printf("--- Message [%s]\r\n", pMessage); + tkms_buff2str(pMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to sign message using RSA with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_SignInit(session, &rsa_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_RSA2048_OBJECT_HANDLE); + } + + /* Sign message */ + if (rv == CKR_OK) + { + signature_length = sizeof(signature); + rv = C_Sign(session, pMessage, length, + signature, &signature_length); + } + + (void)printf("--- Signed ------------------------------------------------------\r\n"); + tkms_buff2str(signature, a_string, signature_length); + (void)printf("--- Signature [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", signature_length); + + /* Verification ------------------------------------------------------------*/ + + /* Configure session to verify message using RSA with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_VerifyInit(session, &rsa_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_RSA2048_OBJECT_HANDLE); + } + + /* Verify message */ + if (rv == CKR_OK) + { + rv = C_Verify(session, pMessage, length, + signature, signature_length); + } + + if (rv == CKR_OK) + { + (void)printf(">>> Message authenticated\r\n"); + } + else + { + (void)printf("XXX Message not authenticated\r\n"); + } + + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/ymodem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/ymodem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/1_Image_UserApp/Src/ymodem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/Src/ymodem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/readme.txt new file mode 100644 index 00000000..3aaad43b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/1_Image_UserApp/readme.txt @@ -0,0 +1,136 @@ +/** + @page 1_Image_UserApp / Firmware Update - User Application Demo + + @verbatim + ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* + * @file readme.txt + * @brief This application shows a User Application + ****************************************************************************** + * + * Copyright (c) 2017 STMicroelectronics. All rights reserved. + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + @endverbatim + +@par Application Description + +This application demonstrates firmware download capabilities and provides a set of functions to test the active +protections offered by Secure Boot and Secure Engine. +It also demonstrates key management services through basic examples and specific boot +mechanism (firmware update decryption, verification...) +A terminal connected with the board via VCOM is needed to communicate with the board and to select which feature +to demonstrate. + +For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" available from +the STMicroelectronics microcontroller website www.st.com. + +@par Keywords + +Security, KMS, SBSFU + +@par Directory contents + + - 1_Image_UserApp/Src/com.c Communication module file + - 1_Image_UserApp/Src/common.c Common module file + - 1_Image_UserApp/Src/flash_if.c Flash interface file + - 1_Image_UserApp/Src/fw_update_app.c Firmware update application + - 1_Image_UserApp/Src/kms_object_update_app.c KMS Blob update application + - 1_Image_UserApp/Src/main.c Main program + - 1_Image_UserApp/Src/se_user_code.c Call user defined services running in Secure Engine + - 1_Image_UserApp/Src/stm32wlxx_it.c Interrupt handlers + - 1_Image_UserApp/Src/system_stm32wlxx.c STM32 system file + - 1_Image_UserApp/Src/test_protections.c Protection test + - 1_Image_UserApp/Src/tkms_app.c tKMS tests + - 1_Image_UserApp/Src/tkms_app_derive_key.c tKMS key derivation tests + - 1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c tKMS encryption/decryption tests + - 1_Image_UserApp/Src/tkms_app_sign_verify.c tKMS signature/verification tests + - 1_Image_UserApp/Src/ymodem.c Ymodem communication module + - 1_Image_UserApp/Inc/com.h Header for com.c file + - 1_Image_UserApp/Inc/common.h Header for common.c file + - 1_Image_UserApp/Inc/flash_if.h Header for flash_if.c file + - 1_Image_UserApp/Inc/fw_update_app.h Header for fw_update_app.c file + - 1_Image_UserApp/Inc/main.h Header for main.c file + - 1_Image_UserApp/Inc/se_user_code.h Header file for se_user_code.c + - 1_Image_UserApp/Inc/sfu_app_new_image.h Definition for the new blob storage and installation + - 1_Image_UserApp/Inc/stm32wlxx_hal_conf.h HAL configuration file + - 1_Image_UserApp/Inc/stm32wlxx_it.h Header for stm32wlxx_it.c file + - 1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h BSP configuration file + - 1_Image_UserApp/Inc/test_protections.h Header for test_protections.c file + - 1_Image_UserApp/Inc/tkms_app.h Header for tkms_app.c file + - 1_Image_UserApp/Inc/ymodem.h Header for ymodem.c file + +@par Hardware and Software environment + + - This example runs on STM32WL55xx devices. + - This example has been tested with NUCLEO-WL55JC RevC board and can be + easily tailored to any other supported device and development board. + - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware + is a feature provided by STM32Cube programmer available on www.st.com. + - This example is based on se_interface_application.o module exported by BFU project. + - This example needs a terminal emulator. + - Microsoft Windows has a limitation whereby paths to files and directories cannot + be longer than 256 characters. Paths to files exceeding that limits cause tools (e.g. compilers, + shell scripts) to fail reading from or writing to such files. + As a workaround, it is advised to use the subst.exe command from within a command prompt to set + up a local drive out of an existing directory on the hard drive, such as: + C:\> subst X: \Firmware + +@par IDE postbuild script + +In order to ease the development process, a postbuild script ("postbuild.bat") is integrated in each IDE project. +This postbuild script: + - is generated when compiling the Secure Engine Core project, + - prepares the firmware image of the user application to be installed in the device. + +A known limitation of this integration occurs when you update the firmware version (parameter of postbuild.bat script). +The IDE does not track this update so you need to force the rebuild of the project manually. + +@par How to use it ? + +Refer to BFU readme and follow steps by steps instructions. + +Once executed, this user application gives access to a menu which allows: + 1 - to download a new firmware : feature not supported in 1 firmware image example + 2 - to test protections (WRP, IWDG, TAMPER) + 3 - to demonstrate how to call user defined services running in Secure Engine + 4 - to provide access to multiple images feature (not supported) + 5 - to validate a firmware image at first start-up (not supported) + a - to demonstrate usage of key management services + +1. Pressing 1 allows to download a new firmware. +Feature not supported in 1 firmware image example + +2. Pressing 2 allows to test protections. + + - CORRUPT IMAGE test (#1): causes a signature verification failure at next boot + - WRP test (#2): causes an error trying to erase write protected code + - IWDG test (#3): causes a reset simulating a deadlock by not refreshing the watchdog + - TAMPER test (#4): causes a reset if a tamper event is detected. In order to generate a tamper event, + user has to connect PC13 (CN7.23) to GND (It may be enough to put your finger close to PC13 (CN7.23)). + +3. Pressing 3 allows to call user defined services running in Secure Engine. +As an example, after selecting the firmware image, SE_APP_GetActiveFwInfo service is called in order +to display the information located in the protected area such as version and size. + +4. This menu is dedicated to multiple images feature. +Feature not available as there is no firmware download area. + +5. This menu is dedicated to image validation. +Feature available under ENABLE_IMAGE_STATE_HANDLING compilation switch, not available in this example. + +a. Pressing a allows to enter specific key management services test menu. +With this menu, you should be able to try encryption/decryption, signature/verification or key derivation mechanisms. + + +Note1 : There is only 1 active slot configured in this example. +Note2 : for Linux users Minicom can be used but to do so you need to compile the UserApp project with the MINICOM_YMODEM + switch enabled (ymodem.h) + + + *

      © COPYRIGHT STMicroelectronics

      + */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_export.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_export.h new file mode 100644 index 00000000..fbe0d145 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_export.h @@ -0,0 +1,100 @@ +/** + ****************************************************************************** + * @file mapping_export.h + * @author MCD Application Team + * @brief This file contains the definitions exported from mapping linker files. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MAPPING_EXPORT_H +#define MAPPING_EXPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported constants --------------------------------------------------------*/ +extern uint32_t __ICFEDIT_intvec_start__; +#define INTVECT_START ((uint32_t)& __ICFEDIT_intvec_start__) +extern uint32_t __ICFEDIT_SE_Startup_region_ROM_start__; +#define SE_STARTUP_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Startup_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_Code_region_ROM_start__; +#define SE_CODE_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Code_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_Code_region_ROM_end__; +#define SE_CODE_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_Code_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_IF_region_ROM_start__; +#define SE_IF_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_IF_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_IF_region_ROM_end__; +#define SE_IF_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_IF_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_Key_region_ROM_start__; +#define SE_KEY_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Key_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_Key_region_ROM_end__; +#define SE_KEY_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_Key_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_CallGate_region_ROM_start__; +#define SE_CALLGATE_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_CallGate_region_ROM_start__) +extern uint32_t __ICFEDIT_SB_region_ROM_start__; +#define SB_REGION_ROM_START ((uint32_t)& __ICFEDIT_SB_region_ROM_start__) +extern uint32_t __ICFEDIT_SB_region_ROM_end__; +#define SB_REGION_ROM_END ((uint32_t)& __ICFEDIT_SB_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_region_RAM_start__; +#define SE_REGION_RAM_START ((uint32_t)& __ICFEDIT_SE_region_RAM_start__) +extern uint32_t __ICFEDIT_SE_region_RAM_end__ ; +#define SE_REGION_RAM_END ((uint32_t)& __ICFEDIT_SE_region_RAM_end__) +extern uint32_t __ICFEDIT_SB_region_RAM_start__ ; +#define SB_REGION_RAM_START ((uint32_t)& __ICFEDIT_SB_region_RAM_start__) +extern uint32_t __ICFEDIT_SB_region_RAM_end__ ; +#define SB_REGION_RAM_END ((uint32_t)& __ICFEDIT_SB_region_RAM_end__) +extern uint32_t __ICFEDIT_SE_region_RAM_stack_top__; +#define SE_REGION_RAM_STACK_TOP ((uint32_t)& __ICFEDIT_SE_region_RAM_stack_top__) + +extern uint32_t __ICFEDIT_KMS_DataStorage_start__ ; +#define KMS_DATASTORAGE_START ((uint32_t)& __ICFEDIT_KMS_DataStorage_start__) +extern uint32_t __ICFEDIT_KMS_DataStorage_end__ ; +#define KMS_DATASTORAGE_END ((uint32_t)& __ICFEDIT_KMS_DataStorage_end__) + + +#if defined (__ICCARM__) || defined(__GNUC__) +extern uint32_t __ICFEDIT_SLOT_Active_1_header__; +#define SLOT_ACTIVE_1_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_1_header__) +extern uint32_t __ICFEDIT_SLOT_Active_1_start__; +#define SLOT_ACTIVE_1_START ((uint32_t)& __ICFEDIT_SLOT_Active_1_start__) +extern uint32_t __ICFEDIT_SLOT_Active_1_end__; +#define SLOT_ACTIVE_1_END ((uint32_t)& __ICFEDIT_SLOT_Active_1_end__) +extern uint32_t __ICFEDIT_SLOT_Active_2_header__; +#define SLOT_ACTIVE_2_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_2_header__) +extern uint32_t __ICFEDIT_SLOT_Active_2_start__; +#define SLOT_ACTIVE_2_START ((uint32_t)& __ICFEDIT_SLOT_Active_2_start__) +extern uint32_t __ICFEDIT_SLOT_Active_2_end__; +#define SLOT_ACTIVE_2_END ((uint32_t)& __ICFEDIT_SLOT_Active_2_end__) +extern uint32_t __ICFEDIT_SLOT_Active_3_header__; +#define SLOT_ACTIVE_3_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_3_header__) +extern uint32_t __ICFEDIT_SLOT_Active_3_start__; +#define SLOT_ACTIVE_3_START ((uint32_t)& __ICFEDIT_SLOT_Active_3_start__) +extern uint32_t __ICFEDIT_SLOT_Active_3_end__; +#define SLOT_ACTIVE_3_END ((uint32_t)& __ICFEDIT_SLOT_Active_3_end__) +extern uint32_t __ICFEDIT_SLOT_Blob_Dwl_1_start__; +#define SLOT_BLOB_DWL_1_START ((uint32_t)& __ICFEDIT_SLOT_Blob_Dwl_1_start__) +extern uint32_t __ICFEDIT_SLOT_Blob_Dwl_1_end__; +#define SLOT_BLOB_DWL_1_END ((uint32_t)& __ICFEDIT_SLOT_Blob_Dwl_1_end__) +#endif /* __ICCARM__ || __GNUC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* MAPPING_EXPORT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_fwimg.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_fwimg.icf similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_fwimg.icf rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_fwimg.icf diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_fwimg_sec.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_fwimg_sec.icf similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_fwimg_sec.icf rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_fwimg_sec.icf diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_sbsfu.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_sbsfu.icf similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_sbsfu.icf rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_sbsfu.icf diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_sbsfu_sec.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_sbsfu_sec.icf similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/EWARM/mapping_sbsfu_sec.icf rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/EWARM/mapping_sbsfu_sec.icf diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_fwimg.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_fwimg.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_fwimg.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_fwimg.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_fwimg_sec.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_fwimg_sec.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_fwimg_sec.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_fwimg_sec.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_sbsfu.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_sbsfu.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_sbsfu.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_sbsfu.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_sbsfu_sec.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_sbsfu_sec.h similarity index 99% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_sbsfu_sec.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_sbsfu_sec.h index 831ee903..d1d04427 100644 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/MDK-ARM/mapping_sbsfu_sec.h +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/MDK-ARM/mapping_sbsfu_sec.h @@ -36,7 +36,7 @@ /* SE Embedded Keys */ #define SE_KEY_REGION_ROM_START (SE_CALLGATE_REGION_ROM_END + 0x1) -#define SE_KEY_REGION_ROM_END (SE_KEY_REGION_ROM_START + 0x2FF) +#define SE_KEY_REGION_ROM_END (SE_KEY_REGION_ROM_START + 0x1FF) /* SE Startup */ #define SE_STARTUP_REGION_ROM_START (SE_KEY_REGION_ROM_END + 1) diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_export.h b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_export.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_export.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_export.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_fwimg.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_fwimg.ld similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_fwimg.ld rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_fwimg.ld diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_fwimg_sec.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_fwimg_sec.ld similarity index 80% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_fwimg_sec.ld rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_fwimg_sec.ld index fa7b4e36..55ea444a 100644 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_fwimg_sec.ld +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_fwimg_sec.ld @@ -5,13 +5,13 @@ /* Slots must be aligned on sector size */ /* Active slot #1 (194 kbytes) */ -SLOT_Active_1_start = 0x0800F800; +SLOT_Active_1_start = 0x08010800; SLOT_Active_1_end = 0x0803FFFF; SLOT_Active_1_header = SLOT_Active_1_start; /* Dwl slot #1 : (2 kbytes) */ -SLOT_Blob_Dwl_1_start = 0x0800F000; -SLOT_Blob_Dwl_1_end = 0x0800F7FF; +SLOT_Blob_Dwl_1_start = 0x08010000; +SLOT_Blob_Dwl_1_end = 0x080107FF; /* Slots not configured */ SLOT_Active_2_header = 0x00000000; diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld new file mode 100644 index 00000000..29efab53 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld @@ -0,0 +1,85 @@ +/* +** LinkerScript +*/ + +/******************************************************************************/ +/* ROM section */ +/******************************************************************************/ + +/* Vector table */ +INTVECT_start = 0x08000000; +Vector_size = 0x200; + +/* SE Code region protected by MPU isolation */ +SE_Code_region_ROM_start = INTVECT_start + Vector_size; +SE_CallGate_region_ROM_start = SE_Code_region_ROM_start; /* No need to do +4 as we have dummy bytes in SE_CoreBin .ld file */ +SE_CallGate_region_ROM_end = SE_Code_region_ROM_start + 0xFF; + +/* SE Embedded Keys */ +SE_Key_region_ROM_start = SE_CallGate_region_ROM_end + 0x1; +SE_Key_region_ROM_end = SE_Key_region_ROM_start + 0x1FF; + +/* SE Startup */ +SE_Startup_region_ROM_start = SE_Key_region_ROM_end + 0x1; +SE_Code_NoKey_region_ROM_start = SE_Startup_region_ROM_start + 0x100; +SE_Code_region_ROM_end = SE_Startup_region_ROM_start + 0x73FF; + +/* SE IF ROM */ +SE_IF_region_ROM_start = SE_Code_region_ROM_end + 0x1; +SE_IF_region_ROM_end = SE_IF_region_ROM_start + 0xEFF; + +/* SBSFU Code region */ +SB_region_ROM_start = SE_IF_region_ROM_end + 0x1; +SB_region_ROM_end = 0x0800CFFF; + +/* KMS Data Storage (NVMS) region protected area */ +/* KMS Data Storage need for 2 images : 4 kbytes * 2 ==> 8 kbytes */ +KMS_DataStorage_start = 0x0800D000; +KMS_DataStorage_end = 0x0800EFFF; + +/* ROM regions size definition */ +SE_CallGate_region_ROM_size = SE_CallGate_region_ROM_end - SE_CallGate_region_ROM_start + 0x1; +SE_Key_region_ROM_size = SE_Key_region_ROM_end - SE_Key_region_ROM_start + 0x1; +SE_Startup_region_ROM_size = SE_Code_NoKey_region_ROM_start - SE_Startup_region_ROM_start; +SE_Code_region_ROM_size = SE_Code_region_ROM_end - SE_Code_region_ROM_start + 0x1; +SE_Code_NoKey_region_ROM_size = SE_Code_region_ROM_end - SE_Code_NoKey_region_ROM_start + 0x1; +SE_IF_region_ROM_size = SE_IF_region_ROM_end - SE_IF_region_ROM_start + 0x1; +SB_region_ROM_size = SB_region_ROM_end - SB_region_ROM_start + 0x1; +KMS_DataStorage_size = KMS_DataStorage_end - KMS_DataStorage_start + 0x1; + +/******************************************************************************/ +/* RAM section */ +/* */ +/******************************************************************************/ + +/* SE RAM region */ +SE_region_RAM_start = 0x20000000; +SE_region_RAM_stack_top = 0x20000C00; /* Secure Engine's private stack */ +SE_region_RAM_end = 0x200033FF; + +/* SBSFU RAM region */ +SB_region_RAM_start = SE_region_RAM_end + 0x1; +SB_region_RAM_end = 0x20007FFF; + +/* RAM regions size definition */ +SE_region_RAM_size = SE_region_RAM_end - SE_region_RAM_stack_top + 0x1; +SB_region_RAM_size = SB_region_RAM_end - SB_region_RAM_start + 0x1; + +/******************************************************************************/ +/* RAM/ROM regions */ +/* */ +/******************************************************************************/ + +MEMORY +{ + INTVECT_ROM_region (rx) : ORIGIN = INTVECT_start, LENGTH = Vector_size + SE_CallGate_ROM_region (rx) : ORIGIN = SE_CallGate_region_ROM_start, LENGTH = SE_CallGate_region_ROM_size + SE_Key_region_ROM (rx) : ORIGIN = SE_Key_region_ROM_start, LENGTH = SE_Key_region_ROM_size + SE_Startup_ROM_region (rx) : ORIGIN = SE_Startup_region_ROM_start, LENGTH = SE_Startup_region_ROM_size + SE_ROM_region (rx) : ORIGIN = SE_CallGate_region_ROM_start, LENGTH = SE_Code_region_ROM_size + SE_Code_NoKey_ROM_region (rx) : ORIGIN = SE_Code_NoKey_region_ROM_start, LENGTH = SE_Code_NoKey_region_ROM_size + SE_IF_ROM_region (rx) : ORIGIN = SE_IF_region_ROM_start, LENGTH = SE_IF_region_ROM_size + SB_ROM_region (rx) : ORIGIN = SB_region_ROM_start, LENGTH = SB_region_ROM_size + SE_RAM_region (xrw) : ORIGIN = SE_region_RAM_stack_top, LENGTH = SE_region_RAM_size + SB_RAM_region (xrw) : ORIGIN = SB_region_RAM_start, LENGTH = SB_region_RAM_size +} diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_sbsfu_sec.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_sbsfu_sec.ld similarity index 92% rename from Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_sbsfu_sec.ld rename to Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_sbsfu_sec.ld index 3c0a9a2b..66bd9215 100644 --- a/Projects/NUCLEO-WL55JC/Applications/BFU_1_Image/Linker_Common/STM32CubeIDE/mapping_sbsfu_sec.ld +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_1_Slot/Linker_Common/STM32CubeIDE/mapping_sbsfu_sec.ld @@ -12,17 +12,17 @@ Vector_size = 0x200; /* SE Code region protected by MPU isolation */ SE_Code_region_ROM_start = INTVECT_start + Vector_size; -SE_CallGate_region_ROM_start = SE_Code_region_ROM_start + 0x4; +SE_CallGate_region_ROM_start = SE_Code_region_ROM_start; /* No need to do +4 as we have dummy bytes in SE_CoreBin .ld file */ SE_CallGate_region_ROM_end = SE_Code_region_ROM_start + 0xFF; /* SE Embedded Keys */ SE_Key_region_ROM_start = SE_CallGate_region_ROM_end + 0x1; -SE_Key_region_ROM_end = SE_Key_region_ROM_start + 0x2FF; +SE_Key_region_ROM_end = SE_Key_region_ROM_start + 0x1FF; /* SE Startup */ SE_Startup_region_ROM_start = SE_Key_region_ROM_end + 0x1; SE_Code_NoKey_region_ROM_start = SE_Startup_region_ROM_start + 0x100; -SE_Code_region_ROM_end = SE_Startup_region_ROM_start + 0x72FF; +SE_Code_region_ROM_end = SE_Startup_region_ROM_start + 0x73FF; /* SE IF ROM */ SE_IF_region_ROM_start = SE_Code_region_ROM_end + 0x1; @@ -30,12 +30,12 @@ SE_IF_region_ROM_end = SE_IF_region_ROM_start + 0xEFF; /* SBSFU Code region */ SB_region_ROM_start = SE_IF_region_ROM_end + 0x1; -SB_region_ROM_end = 0x0800CFFF; +SB_region_ROM_end = 0x0800DFFF; /* KMS Data Storage (NVMS) region protected area */ /* KMS Data Storage need for 2 images : 4 kbytes * 2 ==> 8 kbytes */ -KMS_DataStorage_start = 0x0800D000; -KMS_DataStorage_end = 0x0800EFFF; +KMS_DataStorage_start = 0x0800E000; +KMS_DataStorage_end = 0x0800FFFF; /* ROM regions size definition */ SE_CallGate_region_ROM_size = SE_CallGate_region_ROM_end - SE_CallGate_region_ROM_start + 0x1; diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/app_sfu.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/app_sfu.h new file mode 100644 index 00000000..ef3e6f8a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/app_sfu.h @@ -0,0 +1,243 @@ +/** + ****************************************************************************** + * @file app_sfu.h + * @author MCD Application Team + * @brief This file contains the configuration of SBSFU application. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_SFU_H +#define APP_SFU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "se_crypto_config.h" + +/* Exported constants --------------------------------------------------------*/ +/** + * Use this define to choose the type of Firmware Image Programming you want to use. + * This version supports only 2 modes: + * + * SFU_ENCRYPTED_IMAGE: Encrypted Firmware Image + * The image is received in encrypted format. + * The image must be decrypted to be installed: + * this is done according to the selected crypto scheme, + * see @ref SECBOOT_CRYPTO_SCHEME in the SE_CoreBin part. + * + * SFU_CLEAR_IMAGE: Clear Firmware Image + * The image is received in clear format. + * No decrypt operation is needed before installing the image: + * the selected crypto scheme must be compatible with this choice, + * see @ref SECBOOT_CRYPTO_SCHEME in the SE_CoreBin part. + * + * + */ +#if SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 +#define SFU_IMAGE_PROGRAMMING_TYPE SFU_CLEAR_IMAGE +#else +#define SFU_IMAGE_PROGRAMMING_TYPE SFU_ENCRYPTED_IMAGE +#endif /* SECBOOT_CRYPTO_SCHEME */ + +#define SFU_ENCRYPTED_IMAGE (0U) /*!< The Firmware Image to be installed is downloaded in ENCRYPTED format */ +#define SFU_CLEAR_IMAGE (1U) /*!< The Firmware Image to be installed is downloaded in CLEAR format */ + +#define SFU_DEBUG_MODE /*!< Comment this define to optimize memory footprint (debug mode removed) + No more print on terminal during SBSFU execution */ + +/*#define SFU_VERBOSE_DEBUG_MODE*/ /*!< Uncomment this define when in verbose Debug mode. + this switch activates more debug prints in the console (FSM state info...) */ + + +/*#define SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE*/ /*!< You may uncomment this define when running development tests. + When this switch is activated, the FWIMG part of SB_SFU will + block when an abnormal error is encountered */ + +#if defined(SFU_VERBOSE_DEBUG_MODE) && !defined(SFU_DEBUG_MODE) +#error You cannot activate SFU_VERBOSE_DEBUG_MODE without activating SFU_DEBUG_MODE too. +#endif /* SFU_VERBOSE_DEBUG_MODE && !SFU_DEBUG_MODE */ + +#if defined(SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE) && !defined(SFU_DEBUG_MODE) +#error SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is meant to be used in DEBUG mode +#endif /* SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE && !SFU_DEBUG_MODE */ + +/*#define SFU_TEST_PROTECTION*/ /*!< Auto-test of protections : WRP, PCROP, MPU, FWALL. + Automatically executed @startup */ +#if defined(SFU_TEST_PROTECTION) +#undef SFU_DEBUG_MODE /*!< Remove definition to optimize memory footprint (debug mode removed) */ +#endif /* SFU_TEST_PROTECTION */ + +/** + * SB_SFU status LED. + * The constants below define the LED to be used and the LED blinking frequency to identify some situations. + * This is useful when no log is enabled. + * + * \li The LED blinks every see @ref SFU_COM_YMODEM_DOWNLOAD_TIMEOUT seconds when a local download is waited. + * \li For the other situations, please check the other defines below. + */ +#define SFU_STATUS_LED (LED_GREEN) /*!< LED to be used to provide the SB_SFU status to the end-user */ +#define SFU_STOP_NO_FW_BLINK_DELAY (100U) /*!< Blinks every 100ms when no valid firmware is available and the local + loader feature is disabled - see @ref SECBOOT_USE_LOCAL_LOADER */ +#define SFU_INCORRECT_OB_BLINK_DELAY (250U) /*!< Blinks every 250ms when an Option Bytes issue is detected */ + + +/** + * Optional Features Software Configuration + */ +#if !defined(SFU_TEST_PROTECTION) +#define SECBOOT_LOADER SECBOOT_USE_LOCAL_LOADER /*!< Loader selection inside SBSFU : local/standalone/none */ +#else +#define SECBOOT_LOADER SECBOOT_USE_NO_LOADER /*!< No loader usage forced when SFU_TEST_PROTECTION is set */ +#endif /* SFU_TEST_PROTECTION */ + +#define SECBOOT_USE_LOCAL_LOADER (1U) /*!< local loader feature integrated into SBSFU (YMODEM over UART) */ +#define SECBOOT_USE_STANDALONE_LOADER (2U) /*!< standalone loader : see specific loader project */ +#define SECBOOT_USE_NO_LOADER (3U) /*!< no loader capability at SBSFU stage */ + +/* Uncomment the define below if you want to use minicom with Linux */ +/* #define MINICOM_YMODEM */ /*!< YMODEM protocol handled by MINICOM (Linux): 128 bytes packets */ + +#if defined(MINICOM_YMODEM) +/* Minicom does not accept the debug prints during the YMODEM session */ +#undef SFU_VERBOSE_DEBUG_MODE +#endif /* MINICOM_YMODEM */ + +/* Uncomment the define below if you want to remove the swap area + ==> partial update is not supported in this configuration + ==> image validation is not supported in this configuration */ +/*#define SFU_NO_SWAP*/ /*!< FW upgrade installation process without swap area */ + +/* Multi-images configuration : + - Max : 3 Active images and 3 Download area + - Not necessary same configuration between SFU_NB_MAX_ACTIVE_IMAGE and SFU_NB_MAX_DWL_AREA + - Active slot identified with SFU magic (1,2,3) information from header + - Do not forget to add keys for each image in SE_Corebin/Binary folder + - Master slot : image started in priority if valid + - FW image valide all feature authorized from master slot +*/ +#define SFU_NB_MAX_ACTIVE_IMAGE 1U /*!< 1 active image managed */ +#define SFU_NB_MAX_DWL_AREA 1U /*!< 1 dwl area managed */ +#define MASTER_SLOT SLOT_ACTIVE_1 /*!< SLOT_ACTIVE_1 identified as master slot */ + + +/* The define below allows disabling all security IPs at once. + * + * Enabled: all security IPs (WRP, watchdog...) are disabled. + * Disabled: the security IPs can be used (if their specific compiler switches are enabled too). + * + */ + +#define SECBOOT_DISABLE_SECURITY_IPS /*!< Disable all security IPs at once when activated */ + + +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) + +/* Uncomment the following defines when in Release mode. + In debug mode it can be better to disable some of the following protection + for a better Debug experience (WRP, RDP, IWDG, DAP, etc.) */ + +#define SFU_WRP_PROTECT_ENABLE +#define SFU_RDP_PROTECT_ENABLE +/*#define SFU_TAMPER_PROTECT_ENABLE */ /*!< WARNING : Tamper protection deactivated. As the tamper tamper pin is + neither connected to GND nor to 5V (floating level), there are too many + spurious tamper event detected */ +#define SFU_DAP_PROTECT_ENABLE /*!< WARNING: Be Careful if enabling this protection. Debugger will be disconnected. + It might be difficult to reconnect the Debugger.*/ +#define SFU_DMA_PROTECT_ENABLE +#define SFU_IWDG_PROTECT_ENABLE /*!< WARNING: + 1. Be Careful if enabling this protection. IWDG will be active also after + switching to UserApp: a refresh is needed. + 2. The IWDG reload in the SB_SFU code will have to be tuned depending on your + platform (flash size...)*/ +#define SFU_MPU_PROTECT_ENABLE /*!< MPU protection: + Enables/Disables the MPU protection. + If Secure Engine isolation is ensured by MPU (see SFU_ISOLATE_SE_WITH_MPU in + SE_CoreBin\Inc\se_low_level.h), then this switch also enables/disables it, in + addition to the overall MPU protection. */ +#define SFU_MPU_USERAPP_ACTIVATION /*!< MPU protection during UserApp execution : Only active slot(s) considered as an + executable area */ + + +/*#define SFU_FINAL_SECURE_LOCK_ENABLE */ /*!< WARNING: Should be enabled at the end of product development and test + steps. + When enabling this lock, Static protections cannot be modified any more + and Debug is finally disabled. */ + +#if defined(SFU_FINAL_SECURE_LOCK_ENABLE) +#define SFU_PROTECT_RDP_LEVEL (OB_RDP_LEVEL_2) /*!< RDP level2 for product on the field. Final OB lock, Debug + completely disabled, OB update no more possible */ + + +#else +#define SFU_PROTECT_RDP_LEVEL (OB_RDP_LEVEL_1) /*!< RDP level is set as 1 for debugging purposes. A product on the + field should set it as Level2 */ +#endif /* SFU_FINAL_SECURE_LOCK_ENABLE */ + +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ + +/** + * The define below (SECBOOT_OB_DEV_MODE) determines if the OPTION BYTES should be handled in Development mode or not. + * This define is taken into account only if RDP level 2 is not set. + * If RDP level 2 is set no modification can be done anyway. + * + * Enabled: Option Bytes Development Mode enabled. + * SB_SFU uses a "check and apply" strategy when checking the Option Bytes configuration. + * If an OB is not set though it should be then this setting is automatically corrected. + * This applies only as long as RDP level 2 is not set. + * + * Disabled: Option Bytes Development Mode disabled. + * In this mode the Option Bytes are supposed to be already configured properly when the software starts for + the first time. + * SB_SFU checks the Option Bytes configuration but does not correct it. + * If a problem is detected an error message is reported and the execution stops. + */ +#define SECBOOT_OB_DEV_MODE + + +#define SFU_IWDG_TIMEOUT ((uint32_t)15) /*!< IWDG timeout in seconds (the max. value that can be set here depends on + the prescaler settings: IWDG_PRESCALER_XXX. ) */ + + +/** + * Application Configuration + * + */ +#define SFU_FW_VERSION_START_NUM (1U) /*!< The very first version number a Firmware can have + You can also define an upper bound here if you plan to use it */ + +#define SFU_FW_VERSION_INIT_NUM (1U) /*!< The version number accepted when the header is not valid (either because + no FW installed or due to an attack attempt). Could be different from + SFU_FW_VERSION_START_NUM */ + +/** + * Features compatibility control + */ +#if defined(SFU_NO_SWAP) && defined(ENABLE_IMAGE_STATE_HANDLING) +#warning "ENABLE_IMAGE_STATE_HANDLING not compatible with SFU_NO_SWAP process" +#endif +#if defined(SFU_SECURE_USER_PROTECT_ENABLE) && defined(ENABLE_IMAGE_STATE_HANDLING) +#warning "ENABLE_IMAGE_STATE_HANDLING not compatible with SFU_SECURE_USER_PROTECT_ENABLE process" +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_SFU_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_boot.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_boot.c new file mode 100644 index 00000000..e748ea93 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_boot.c @@ -0,0 +1,1715 @@ +/** + ****************************************************************************** + * @file sfu_boot.c + * @author MCD Application Team + * @brief SFU BOOT module + * This file provides firmware functions to manage the following + * functionalities of the Secure Boot: + * + Initialization and de-initialization functions + * + Secure Boot Control functions + * + Secure Boot State functions + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_BOOT_C + +/* Includes ------------------------------------------------------------------*/ +#include "string.h" +#include "sfu_boot.h" +#include "sfu_loader.h" +#include "sfu_low_level_security.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level.h" +#include "sfu_fsm_states.h" +#include "sfu_error.h" +#include "stm32wlxx_it.h" /* required for the HAL Cube callbacks */ + +/* + * The sfu_com init is provided by the sfu_com_trace module by default. + * If not, then it is taken from the sfu_com_loader module. + */ +#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) +#include "sfu_trace.h" +#else +#include "sfu_trace.h" /* needed anyhow even if the defines will be empty */ +#include "sfu_com_loader.h" /* needed only for the COM init/de-init */ +#endif /* SFU_DEBUG_MODE || SFU_TEST_PROTECTION */ +#include "se_def.h" +#include "se_interface_bootloader.h" /* sfu_boot is the bootloader core part */ +#include "sfu_new_image.h" /* the local loader is a kind of "application" running in SB_SFU so it needs the + services to install a FW image */ +#include "sfu_fwimg_services.h" /* sfu_boot uses the services of the FWIMG module */ +#include "sfu_test.h" /* auto tests */ +#include "sfu_fwimg_internal.h" + +#ifdef KMS_ENABLED +#include "tkms.h" +#include "sfu_kms.h" +#endif /* KMS_ENABLED */ + +/* Private typedef -----------------------------------------------------------*/ +typedef struct +{ + SFU_BOOT_StateMachineTypeDef PrevState; /*!< The previous state of the State Machine */ + SFU_BOOT_StateMachineTypeDef CurrState; /*!< The current state of the State Machine */ +} SFU_BOOT_StateMachineContextTypeDef; /*!< Specifies a structure containing the State Machine context + information using during the SM evolution. */ + +/* Private defines -----------------------------------------------------------*/ +#define EXEC_ID_SECURE_BOOT 0U /*!< ID for Secure Boot */ +#define EXEC_ID_USER_APP 1U /*!< ID for User App */ +#define IS_VALID_EXEC_ID(EXEC_ID) (((EXEC_ID) == EXEC_ID_SECURE_BOOT) || \ + ((EXEC_ID) == EXEC_ID_USER_APP)) /*!< Check for valid ID */ + +#define RESERVED_VALUE (0xFEU) /*!< Reserved value. The reserved field used inside the LastExecStatus of the BootInfo is + maintained for future customization/expansion of the field itself */ + +#define SFU_STATE_INITIAL SFU_STATE_CHECK_STATUS_ON_RESET /*!< Define the initial state*/ + +/* Private macros ------------------------------------------------------------*/ +#define SFU_SET_SM_IF_CURR_STATE(Status, SM_STATE_OK, SM_STATE_FAILURE) \ + do{ \ + m_StateMachineContext.PrevState = m_StateMachineContext.CurrState; \ + if (Status == SFU_SUCCESS){ \ + m_StateMachineContext.CurrState = SM_STATE_OK; \ + } \ + else { \ + m_StateMachineContext.CurrState = SM_STATE_FAILURE; \ + } \ + }while(0) /*!< Set a State Machine state according to the 'Status' value*/ + + +#define SFU_SET_SM_CURR_STATE(NewState) \ + do{ \ + m_StateMachineContext.PrevState = m_StateMachineContext.CurrState; \ + m_StateMachineContext.CurrState = NewState; \ + }while(0) /*!< Set a State Machine state*/ + +/* Private variables ---------------------------------------------------------*/ +/*!< Static member variables representing the StateMachine context used during the StateMachine evolution. */ +static __IO SFU_BOOT_StateMachineContextTypeDef m_StateMachineContext = {SFU_STATE_INITIAL, + SFU_STATE_INITIAL + }; + +/*!< Static member variables identifyng the slots to be processed by secure firmware update . */ +static uint32_t m_DwlSlotToInstall = SLOT_INACTIVE; +static uint32_t m_ActiveSlotToResume = SLOT_INACTIVE; +static uint32_t m_ActiveSlotToRollback = SLOT_INACTIVE; +static uint32_t m_ActiveSlotToExecute = SLOT_INACTIVE; + +/* Global variables ----------------------------------------------------------*/ +/** + * This variable indicates if at boot-up the FW presence check has already been performed or not: + * \li It is reset when the FW status has already been checked once and no FW is present + * \li (see @ref SFU_BOOT_SM_CheckUserFwStatus) + * \li It is used to display some messages only once in the teraterm console + * \li It is used to determine if the user button must be pressed before waiting for a local download to start + * \li This is used at LocalDownload and CheckUserFwStatus stages. + */ +uint8_t initialDeviceStatusCheck; + +/** + * Flow control initial values. + * - Security protections flow (static + dynamic) + * - Crypto operations flow (authentication, integrity) + */ +uint32_t uFlowProtectValue = FLOW_CTRL_INIT_VALUE; +uint32_t uFlowCryptoValue = FLOW_CTRL_INIT_VALUE; + +/* Private function prototypes -----------------------------------------------*/ +static SFU_ErrorStatus SFU_BOOT_Init(void); +static SFU_ErrorStatus SFU_BOOT_DeInit(void); +static void SFU_BOOT_BspConfiguration(void); +static SFU_ErrorStatus SFU_BOOT_SM_Run(void); +static void SFU_BOOT_SM_CheckStatusOnReset(void); +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +static void SFU_BOOT_SM_CheckNewFwToDownload(void); +static void SFU_BOOT_SM_DownloadNewUserFw(void); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +#ifdef KMS_ENABLED +static void SFU_BOOT_SM_CheckKMSBlobToInstall(void); +static void SFU_BOOT_SM_InstallKMSBlob(void); +#endif /* KMS_ENABLED */ +static void SFU_BOOT_SM_CheckUserFwStatus(void); +static void SFU_BOOT_SM_VerifyUserFwSignature(void); +static void SFU_BOOT_SM_ExecuteUserFw(void); +static void SFU_BOOT_SM_HandleCriticalFailure(void); +static void SFU_BOOT_SM_RebootStateMachine(void); +static void SFU_BOOT_SM_InstallNewUserFw(void); +static void SFU_BOOT_SM_ResumeInstallNewUserFw(void); +static void SFU_BOOT_SM_RollbackInstallPrevUserFw(void); +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +static SFU_ErrorStatus SFU_BOOT_LaunchStandaloneLoader(void); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +static SFU_ErrorStatus SFU_BOOT_SystemSecurity_Config(void); +static SFU_ErrorStatus SFU_BOOT_CheckApplySecurityProtections(void); +static SFU_ErrorStatus SFU_BOOT_SecuritySafetyCheck(void); +static void SFU_BOOT_ManageResetSources(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief This function starts the secure boot service and returns only if a configuration issue occurs. + * In the nominal case, the bootloader service runs until the user application is launched. + * When no valid user application can be run (after installing a new image or not), + * if the local loader feature is not enabled then the execution stops, + * otherwise a local download will be awaited. + * If the state machine encounters a major issue then a reboot is triggered. + * @param None. + * @note Please note that this service initializes all the required sub-services and rely on them to perform its tasks. + * @note Constraints + * 1. The system initialization must be completed (HAL, clocks, peripherals...) before calling this function. + * 2. This function also takes care of BSP initialization after enabling the secure mode. + * The BSP init code can be added in @ref SFU_BOOT_BspConfiguration(). + * 3. No other entity should handle the initialization of the Secure Engine. + * 4. The other SB_SFU services should NOT be configured by other entities if this service is used (the previous + * configurations will be overwritten). + * 5. The other SB_SFU services should NOT be used by any other entity if this service is running. + * 6. When returning from this function a reboot should be triggered (NVIC_SystemReset) after processing the + * error cause. + * 7. The caller must be prepared to never get the hand back after calling this function (jumping in user + * application by default or entering local loader state if local loader is enabled or rebooting to install a + * new image). + * @note Settings are handled at compilation time: + * 1. See compiler switches in main.h for secure IPs settings + * 2. The trace system is configured in the sfu_trace.h file + * @retval SFU_BOOT_InitErrorTypeDef error code as the function returns only if a critical failure occurs at init + * stage. + */ +SFU_BOOT_InitErrorTypeDef SFU_BOOT_RunSecureBootService() +{ + SFU_BOOT_InitErrorTypeDef e_ret_code = SFU_BOOT_INIT_ERROR; + + /* + * initialize Secure Engine variable as secure Engine is managed as a completely separate binary - not + * "automatically" managed by SBSFU compiler command + */ + if (SE_Startup() == SE_SUCCESS) + { + /* Security Configuration */ + if (SFU_BOOT_SystemSecurity_Config() == SFU_SUCCESS) + { + /* Board BSP Configuration */ + SFU_BOOT_BspConfiguration(); + + /* Configure the Secure Boot and start the State machine */ + if (SFU_BOOT_Init() == SFU_SUCCESS) + { + /* Start the Secure Boot State Machine */ + (void) SFU_BOOT_SM_Run(); + } + else + { + /* failure when initializing the secure boot service */ + e_ret_code = SFU_BOOT_INIT_FAIL; + } + } + else + { + /* failure when configuring the security IPs */ + e_ret_code = SFU_BOOT_SECIPS_CFG_FAIL; + } + } + else + { + /* failure at secure engine initialization stage */ + e_ret_code = SFU_BOOT_SECENG_INIT_FAIL; + } + + /* + * This point should not be reached unless a critical init failure occurred + * Return the error code + */ + return (e_ret_code); +} + +/** + * @brief Force System Reboot + * @param None + * @retval None + */ +void SFU_BOOT_ForceReboot(void) +{ + /* + * WARNING: The follow TRACEs are for debug only. This function could be called + * inside an IRQ so the below printf could not be executed or could generate a fault! + */ + TRACE("\r\n========= End of Execution =========="); + TRACE("\r\n\r\n\r\n"); + + /* This is the last operation executed. Force a System Reset. */ + NVIC_SystemReset(); +} + +/** + * @brief Initialize the Secure Boot State machine. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + + /* + * We start the execution at boot-up (display all messages in teraterm console, check the trigger to force a local + * download) + */ + initialDeviceStatusCheck = 1U; + + /* Call the Hardware Abstraction Layer Init implemented for the specific MCU */ + if (SFU_LL_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* Flash interface initialization */ + if (SFU_LL_FLASH_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* The COM modules is required only if the trace or the local download is enabled */ +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) + /* Call the COM module Init (already handled in SFU_BOOT_SystemSecurity_Config) */ + if (SFU_COM_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* SECBOOT_USE_LOCAL_LOADER || SFU_DEBUG_MODE || SFU_TEST_PROTECTION*/ + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + /* Call the SFU_LOADER module Init */ + if (SFU_LOADER_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* SECBOOT_USE_LOCAL_LOADER */ + + /* Call the Exception module Init */ + if (SFU_EXCPT_Init() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* Call the image handling Init */ + if (SFU_IMG_InitImageHandling() != SFU_IMG_INIT_OK) + { + return SFU_ERROR; + } /* else continue */ + +#ifdef SFU_TEST_PROTECTION + SFU_TEST_Init(); +#endif /* SFU_TEST_PROTECTION */ + + TRACE("\r\n\r\n"); + TRACE("\r\n======================================================================"); + TRACE("\r\n= (C) COPYRIGHT 2017 STMicroelectronics ="); + TRACE("\r\n= ="); + TRACE("\r\n= Secure Boot and Secure Firmware Update ="); + TRACE("\r\n======================================================================"); + TRACE("\r\n\r\n"); + + /* Initialize the Secure Engine that will be used for all the most critical operations */ + if (SE_Init(&e_se_status, SystemCoreClock) != SE_SUCCESS) + { + TRACE("\r\n= [SBOOT] SECURE ENGINE INITIALIZATION CRITICAL FAILURE!"); + } + else + { + e_ret_status = SFU_SUCCESS; + TRACE("\r\n= [SBOOT] SECURE ENGINE INITIALIZATION SUCCESSFUL"); + } + + return e_ret_status; +} + +/** + * @brief DeInitialize the Secure Boot State machine. + * @param None + * @note Please note that in this example the de-init function is used only once to avoid a compiler warning. + * The bootloader can terminate: + * 1. with an init failure : no de-init needed + * 2. with a critical failure leading to a reboot: no de-init needed as long as no persistent info is stored + * by this function. + * 3. when launching the user app: de-init may be called here if required as long as it does not disengage the + * required security mechanisms. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_DeInit(void) +{ + if (SFU_EXCPT_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + if (SFU_LOADER_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* SECBOOT_USE_LOCAL_LOADER */ + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) + if (SFU_COM_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) */ + + if (SFU_LL_DeInit() != SFU_SUCCESS) + { + return SFU_ERROR; + } + + return SFU_SUCCESS; +} + +/** + * @brief BSP Initialization. + * Called when the secure mode is enabled. + * @note The BSP configuration should be handled only in this function. + * @param None + * @retval None + */ +static void SFU_BOOT_BspConfiguration() +{ + /* LED Init*/ + (void) BSP_LED_Init(SFU_STATUS_LED); + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + /* User Button */ + BUTTON_INIT(); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +} + +/** + * @brief Execute the Secure Boot state machine. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_SM_Run(void) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + void (*fnStateMachineFunction)(void); + static void (* fnStateMachineTable[])(void) = {SFU_BOOT_SM_CheckStatusOnReset, +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_BOOT_SM_CheckNewFwToDownload, + SFU_BOOT_SM_DownloadNewUserFw, +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +#ifdef KMS_ENABLED + SFU_BOOT_SM_CheckKMSBlobToInstall, + SFU_BOOT_SM_InstallKMSBlob, +#endif /* KMS_ENABLED */ + SFU_BOOT_SM_CheckUserFwStatus, + SFU_BOOT_SM_InstallNewUserFw, + SFU_BOOT_SM_VerifyUserFwSignature, + SFU_BOOT_SM_ExecuteUserFw, + SFU_BOOT_SM_ResumeInstallNewUserFw, + SFU_BOOT_SM_RollbackInstallPrevUserFw, + SFU_BOOT_SM_HandleCriticalFailure, + SFU_BOOT_SM_RebootStateMachine + }; + + /* Start the State Machine loop/evolution */ + while (e_ret_status == SFU_SUCCESS) + { + /* Always execute a security/safety check before moving to the next state */ + if (SFU_BOOT_SecuritySafetyCheck() == SFU_SUCCESS) + { + /* Get the right StateMachine function according to the current state */ + fnStateMachineFunction = fnStateMachineTable[(uint8_t)m_StateMachineContext.CurrState]; + + /* Call the State Machine function associated to the current state */ + fnStateMachineFunction(); + } + else + { + e_ret_status = SFU_ERROR; + } + } + + /* If the State Machine cannot evolve anymore, reboot is the only option */ + + /* Set the error before forcing a reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_UNKNOWN); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + + return e_ret_status; +} + +/** @brief Check the Reset status in order to understand the last cause of Reset + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_CheckStatusOnReset(void) +{ + TRACE("\r\n= [SBOOT] STATE: CHECK STATUS ON RESET"); + + /* Check the wakeup sources */ + SFU_BOOT_ManageResetSources(); + + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + /* When the local loader feature is supported we need to check if a local download is requested */ + SFU_SET_SM_CURR_STATE(SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD); +#else +#ifdef KMS_ENABLED + /* When the local loader feature is disabled go directly to the check of the KMS blob presence */ + SFU_SET_SM_CURR_STATE(SFU_STATE_CHECK_KMS_BLOB_TO_INSTALL); +#else + /* When the local loader feature is disabled go directly to the check of the FW status */ + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_STATUS); +#endif /* KMS_ENABLED */ +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +} + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * @brief Check if a new UserApp firmware is available for downloading. + * When entering this state from SFU_STATE_CHECK_STATUS_ON_RESET (initialDeviceStatusCheck=1) it is required + * to press the user button to force the local download. + * When entering this state from SFU_STATE_VERIFY_USER_FW_STATUS the local download is awaited automatically + * (because there is no other action to do). + * @param None + * @note This function must set the next State Machine State. + * @retval None + */ +static void SFU_BOOT_SM_CheckNewFwToDownload(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + + if (STANDALONE_LOADER_STATE == STANDALONE_LOADER_DWL_REQ) + { + TRACE("\r\n= [SBOOT] STATE: execution standalone loader"); + e_ret_status = SFU_BOOT_LaunchStandaloneLoader(); + + /* This is unreachable code (dead code) in principle... + At this point we should not be able to reach the following instructions. + If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); + return; + } +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + + if (initialDeviceStatusCheck == 1U) + { + /* At boot-up, before checking the FW status, a local download can be forced thanks to the user button */ + TRACE("\r\n= [SBOOT] STATE: CHECK NEW FIRMWARE TO DOWNLOAD"); + if (0U != BUTTON_PUSHED()) + { + /* Download requested */ + e_ret_status = SFU_SUCCESS; + } + else + { + e_ret_status = SFU_ERROR; + } + } + else + { + /* + * The FW status has already been checked and no FW can be launched: no need to check the trigger, wait for a local + * download to start + */ + e_ret_status = SFU_SUCCESS; + } + +#ifdef KMS_ENABLED + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_DOWNLOAD_NEW_USER_FW, SFU_STATE_CHECK_KMS_BLOB_TO_INSTALL); +#else + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_DOWNLOAD_NEW_USER_FW, SFU_STATE_VERIFY_USER_FW_STATUS); +#endif /* KMS_ENABLED */ + +} +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER)*/ + +#ifdef KMS_ENABLED +/** + * @brief Check if a KMSBlob is waiting for installation. + * This state can be entered only from SFU_STATE_CHECK_STATUS_ON_RESET when the local loader feature is + * disabled. + * This state can be entered only from SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD when the local loader feature is + * enabled. + * In this latter case, + * if a new Firmware download is requested, + * it has priority over the KMS blob installation, + * and the KMS blob installation request will be lost. + * @param None + * @note This function must set the next State Machine State. + * @retval None + */ +static void SFU_BOOT_SM_CheckKMSBlobToInstall(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_KMS_BlobInstallStateTypeDef e_PendingInstallStatus; + + /* At boot-up, before checking the FW status, we must check if a KMS blob installation is pending */ + TRACE("\r\n= [SBOOT] STATE: CHECK KMS BLOB TO INSTALL"); + + /* Check if a Blob Installation is requested or on-going */ + e_PendingInstallStatus = SFU_KMS_CheckPendingBlobInstallation(); + + if (SFU_KMS_NO_BLOBUPDATE != e_PendingInstallStatus) + { + /* Blob installation requested */ + e_ret_status = SFU_SUCCESS; + } + + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_INSTALL_KMS_BLOB, SFU_STATE_VERIFY_USER_FW_STATUS); +} + +/** + * @brief Check if a KMSBlob is waiting for install. + * When entering this state from SFU_STATE_CHECK_STATUS_ON_RESET (initialDeviceStatusCheck=1) it is required + * to press the user button to force the local download. + * When entering this state from SFU_STATE_VERIFY_USER_FW_STATUS the local download is awaited automatically + * (because there is no other action to do). + * @param None + * @note This function must set the next State Machine State. + * @retval None + */ +static void SFU_BOOT_SM_InstallKMSBlob(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t *pBlobHdr; + uint8_t *pBlobInFlash; + CK_RV e_status; + + /* At boot-up, Managing ImportBlob through KMS services. */ + TRACE("\r\n= [SBOOT] STATE: INSTALL KMS BLOB"); + + /* Here we will Launch SE service to take consume the Blob */ + /* When the Service confirms that the Blob is installed, then we can erase the SWAP */ + e_ret_status = SFU_KMS_GetBlobInstallInfo(&pBlobHdr, &pBlobInFlash); + if (e_ret_status != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN RETRIEVING BLOB LOCATION"); + } + else + { + /* Initialize KMS in order to be able to import blob using internal algorithms */ + e_status = C_Initialize(NULL); + if (e_status == CKR_OK) + { + /* we do not take the return value into account as we will not retry the import in case of issue */ + e_status = C_STM_ImportBlob(pBlobHdr, pBlobInFlash); + + if (e_status != CKR_OK) + { + (void)C_Finalize(NULL); + } + else + { + e_status = C_Finalize(NULL); + } + } + + if (e_status != CKR_OK) + { + TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN COMMUNICATING WITH KMS"); + } + + /* In any case, we remove the Blob To Install (regardless of the result) */ + e_ret_status = SFU_KMS_EraseBlob(); + + if (e_ret_status != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] INSTALL KMS: ERROR WHEN ERASING KMS BLOB"); + } + + /* Display the KMS import result */ + switch (e_status) + { + case CKR_OK: + TRACE("\r\n= [SBOOT] INSTALL KMS: KMS BLOB WELL INSTALLED"); + e_ret_status = SFU_SUCCESS; + break; + + case CKR_SIGNATURE_INVALID: + /* At boot-up, Crypto Error when trying to install KMSBlob. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: BLOB AUTHENT ERROR WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + case CKR_DATA_INVALID: + /* At boot-up, Crypto Error when trying to install KMSBlob. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: BLOB FORM ERROR WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + case CKR_DEVICE_ERROR: + /* At boot-up, NVM Error when trying to install KMSBlob. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: NVM ERROR WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + case CKR_OPERATION_ACTIVE: + /* At boot-up, trying to install KMSBlob while KMS is being use. */ + TRACE("\r\n= [SBOOT] INSTALL KMS: KMS KEYS IN USE WHEN INSTALLING KMS BLOB"); + e_ret_status = SFU_ERROR; + break; + + default: + TRACE("\r\n= [SBOOT] INSTALL KMS: UNKNOWN STATUS"); + e_ret_status = SFU_ERROR; + break; + } + } + + /* Set the next State Machine regardless of the KMS import result */ + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_STATUS); +} + +#endif /* KMS_ENABLED */ + + +/** + * @brief Check the Status of the Fw Image to work on in order to set the next + * State Machine state accordingly + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_CheckUserFwStatus(void) +{ +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_ErrorStatus e_ret_status = SFU_ERROR; +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + SFU_IMG_ImgInstallStateTypeDef e_PendingInstallStatus; + uint32_t i; + + + if (initialDeviceStatusCheck == 1U) + { + TRACE("\r\n= [SBOOT] STATE: CHECK USER FW STATUS"); + } + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + if (STANDALONE_LOADER_STATE == STANDALONE_LOADER_INSTALL_REQ) + { + /* Read header in dwl slot */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &fw_image_header_validated, (uint8_t *) SlotStartAdd[SLOT_DWL_1], + sizeof(SE_FwRawHeaderTypeDef)); + if (e_ret_status == SFU_SUCCESS) + { + /* + * Notify the Secure Boot that a new image has been downloaded + */ + e_ret_status = SFU_IMG_InstallAtNextReset((uint8_t *) &fw_image_header_validated); + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status == SFU_ERROR) + { + TRACE("\r\n\t Cannot memorize that a new image has been downloaded."); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + /* In all cases, standard SBSFU start-up at next reset */ + STANDALONE_LOADER_STATE = STANDALONE_LOADER_NO_REQ; + } +#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ + + /* Check if there is a pending action related to a FW update procedure */ + e_PendingInstallStatus = SFU_IMG_CheckPendingInstallation(&m_DwlSlotToInstall, &m_ActiveSlotToResume, + &m_ActiveSlotToRollback); + + switch (e_PendingInstallStatus) + { + case SFU_IMG_FWIMAGE_ROLLBACK: + /* + * The new FW image has not been validated : rollback requested @ next reset + * Rollback is done assuming the previous image was backed-up in corresponding dwl slot + * As example : new image installed in SLOT_ACTIVE_2. Previous image was backed-up in SLOT_DWL_2 + */ + /* Identify corresponding backed-up slot */ + m_DwlSlotToInstall = m_ActiveSlotToRollback - SLOT_ACTIVE_1 + SLOT_DWL_1; + TRACE("\r\n\t Installation not validated: rollback procedure initiated (SLOT_ACTIVE_%d / SLOT_DWL_%d)", + m_ActiveSlotToRollback, m_DwlSlotToInstall - SLOT_DWL_1 + 1U); + SFU_SET_SM_CURR_STATE(SFU_STATE_ROLLBACK_PREV_USER_FW); + break; + + case SFU_IMG_FWUPDATE_STOPPED: + /* The installation of a downloaded FW has been interrupted */ + /* We perform a resume of the installation */ + TRACE("\r\n\t Installation Failed: resume installation procedure initiated (SLOT_ACTIVE_%d / SLOT_DWL_%d)", + m_ActiveSlotToResume, m_DwlSlotToInstall - SLOT_DWL_1 + 1U); + SFU_SET_SM_CURR_STATE(SFU_STATE_RESUME_INSTALL_NEW_USER_FW); + break; + + case SFU_IMG_FWIMAGE_TO_INSTALL: + /* + * A new FW is detected in the dwl slot and ready to be installed + */ + TRACE("\r\n\t New Fw to be installed from slot SLOT_DWL_%d", m_DwlSlotToInstall - SLOT_DWL_1 + 1U); + SFU_SET_SM_CURR_STATE(SFU_STATE_INSTALL_NEW_USER_FW); + break; + + case SFU_IMG_NO_FWUPDATE: + /* + * No FW image installation pending : + * 1- Priority to MASTER_SLOT : check if a firmware is detected + * 2- No firmware identified : verify other slots and start execution on the last detected firmware + * 3- No active firmware candidate for execution ==> Local download + * + * This strategy can be adapted by removing for example execution of step2 ==> focus only on MASTER_SLOT. + */ + m_ActiveSlotToExecute = 0U; + + /* 1- Priority to MASTER_SLOT : check if a firmware is detected */ + if (MASTER_SLOT != 0xFFU) + { + if (SFU_SUCCESS == SFU_IMG_DetectFW(MASTER_SLOT)) + { + m_ActiveSlotToExecute = MASTER_SLOT; + TRACE("\r\n\t A FW is detected in the slot SLOT_ACTIVE_%d", m_ActiveSlotToExecute); + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_SIGNATURE); + } + } + + /* 2- No firmware identified : verify other slots and start execution on the last detected firmware */ + if (m_ActiveSlotToExecute == 0U) + { + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) /* Slot configured ? */ + { + if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) + { + m_ActiveSlotToExecute = SLOT_ACTIVE_1 + i; + TRACE("\r\n\t A FW is detected in the slot SLOT_ACTIVE_%d", m_ActiveSlotToExecute); + SFU_SET_SM_CURR_STATE(SFU_STATE_VERIFY_USER_FW_SIGNATURE); + } + } + } + } + + /* 3- No active firmware candidate for execution ==> Local download */ + if (m_ActiveSlotToExecute == 0U) + { + /* Control if all active slot are empty */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) /* Slot configured ? */ + { + if (SFU_IMG_VerifyEmptyActiveSlot(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* + * We should never reach this code. + * Could come from an attack ==> as an example we invalidate current firmware. + */ + TRACE("\r\n\t Slot SLOT_ACTIVE_%d not empty : erasing ...", SLOT_ACTIVE_1 + i); + (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ + } + } + } + + /* + * No valid FW is present in the active slot + * and there is no FW to be installed in UserApp download area: local download (when possible) + */ + if (1U == initialDeviceStatusCheck) + { + TRACE("\r\n\t No valid FW found in the active slots nor new FW to be installed"); +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + /* Waiting for a local download is automatic, no trigger required. */ + TRACE("\r\n\t Waiting for the local download to start... "); +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + initialDeviceStatusCheck = 0U; +#ifdef SFU_TEST_PROTECTION + SFU_TEST_Reset(); +#endif /* SFU_TEST_PROTECTION */ + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + else + { + /* + * No ELSE branch (except for verbose debug), because the FW status is checked only once per boot: + * If a FW is present in the active slot => it is checked then launched. + * If there is a FW to install => the installation procedure starts. + * If no FW is present and no installation is pending: + * - if the local loader feature is enabled we enter the local download state + * - if the local loader feature is disabled, the execution is stopped. + */ + TRACE("\r\n\t Abnormal case: SFU_STATE_VERIFY_USER_FW_STATUS should not be entered more than once per boot."); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_SET_SM_CURR_STATE(SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD); +#else + /* + * When the local loader feature is disabled it is not possible to enter the local download state. + * Rebooting automatically or keeping on checking the FW status would not necessarily be better. + * So we end up waiting for the user to reboot (or the IWDG to expire). + */ + TRACE("\r\n\t No valid FW and no local loader: execution stopped.\r\n"); + while (1 == 1) + { + (void) BSP_LED_Toggle(SFU_STATUS_LED); + HAL_Delay(SFU_STOP_NO_FW_BLINK_DELAY); + } +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + } + break; + + default: + TRACE("\r\n\t Flash State Unknown, Critical failure"); + /* If not in one of the previous state, something bad occurred */ + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + break; + } +} + + +#if SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER +/** + * @brief A new UserApp Fw was available. Start to download it + * @param None + * @note Reset is generated at by standalone loader when FW is downloaded. + * @retval None + */ +static void SFU_BOOT_SM_DownloadNewUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + TRACE("\r\n= [SBOOT] STATE: DOWNLOAD NEW USER FIRMWARE"); + + /* Jump into standalone loader */ + STANDALONE_LOADER_STATE = STANDALONE_LOADER_DWL_REQ; + e_ret_status = SFU_BOOT_LaunchStandaloneLoader(); + + /* This is unreachable code (dead code) in principle... + At this point we should not be able to reach the following instructions. + If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} +#elif (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) +/** + * @brief A new UserApp Fw was available. Start to download it + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_DownloadNewUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_LOADER_StatusTypeDef e_ret_status_app = SFU_LOADER_ERR_COM; + uint32_t dwl_slot; + uint32_t u_size = 0; + + TRACE("\r\n= [SBOOT] STATE: DOWNLOAD NEW USER FIRMWARE"); + + /* + * Download area will be chosen as following. After header analysis : + * - same DWL slot number as SFU magic number, if the slot is configured. + * As example, we will choose SLOT_DWL_2 for SFU2 magic in the FW header + * - by default : SLOT_DWL_1 + */ + e_ret_status = SFU_LOADER_DownloadNewUserFw(&e_ret_status_app, &dwl_slot, &u_size); + if (e_ret_status == SFU_SUCCESS) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t FwSize=%d | PartialFwSize=%d | PartialFwOffset=%d | %d bytes received", + fw_image_header_validated.FwSize, fw_image_header_validated.PartialFwSize, + fw_image_header_validated.PartialFwOffset, u_size); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + /* Read header in dwl slot */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &fw_image_header_validated, (uint8_t *) SlotStartAdd[dwl_slot], + sizeof(SE_FwRawHeaderTypeDef)); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* + * Notify the Secure Boot that a new image has been downloaded + * by calling the SE interface function to trigger the installation procedure at next reboot. + */ + if (SFU_IMG_InstallAtNextReset((uint8_t *) &fw_image_header_validated) != SFU_SUCCESS) + { + /* Erase downloaded image */ + (void) SFU_IMG_EraseDownloadedImg(dwl_slot); + + /* no specific error cause set */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Cannot memorize that a new image has been downloaded."); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + else + { + /* Erase downloaded image */ + (void) SFU_IMG_EraseDownloadedImg(dwl_slot); + + /* Memorize the specific error cause if any before handling this critical failure */ + switch (e_ret_status_app) + { + case SFU_LOADER_ERR_COM: + SFU_EXCPT_SetError(SFU_EXCPT_COM_ERR); + break; + case SFU_LOADER_ERR_FW_VERSION: + SFU_EXCPT_SetError(SFU_EXCPT_VERSION_ERR); + break; + case SFU_LOADER_ERR_FW_LENGTH: + SFU_EXCPT_SetError(SFU_EXCPT_FW_TOO_BIG); + break; + case SFU_LOADER_ERR_AUTH_FAILED: + SFU_EXCPT_SetError(SFU_EXCPT_HEADER_AUTH_ERR); + break; + case SFU_LOADER_ERR_FLASH: + SFU_EXCPT_SetError(SFU_EXCPT_FLASH_ERR); + break; + case SFU_LOADER_ERR_CRYPTO: + SFU_EXCPT_SetError(SFU_EXCPT_DECRYPT_ERR); + break; + default: + /* no specific error cause */ + break; + } + } /* else error with no specific error cause */ + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_REBOOT_STATE_MACHINE, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} +#endif /* SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER */ + +/** + * @brief Install the new UserApp Fw + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_InstallNewUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + TRACE("\r\n= [SBOOT] STATE: INSTALL NEW USER FIRMWARE "); + /* Double security check : + - testing "static protections" twice will avoid basic hardware attack + - flow control reached : dynamic protections checked + - re-execute static then dynamic check + - errors caught by FLOW_CONTROL ==> infinite loop */ + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); + FLOW_CONTROL_INIT(uFlowProtectValue, FLOW_CTRL_INIT_VALUE); + e_ret_status = SFU_LL_SECU_CheckApplyStaticProtections(); + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_STATIC_PROTECT); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_SECU_CheckApplyRuntimeProtections(SFU_SECOND_CONFIGURATION); + } + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); + if (e_ret_status != SFU_SUCCESS) + { + /* + * Due to previous flow control, we should never reach this code : + * Critical failure management if installation failed + */ + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + return; + } + + /* Check the candidate version vs current active version */ + e_ret_status = SFU_IMG_CheckCandidateVersion(m_DwlSlotToInstall); + + if (SFU_SUCCESS != e_ret_status) + { + /* Erase downloaded FW in case of authentication/integrity error */ + (void) SFU_IMG_EraseDownloadedImg(m_DwlSlotToInstall); + } + else + { + /* Secure coding : double check the candidate version vs current active version */ + e_ret_status = SFU_IMG_CheckCandidateVersion(m_DwlSlotToInstall); + } + + if (SFU_SUCCESS == e_ret_status) + { + /* Launch the Firmware Installation procedure */ + e_ret_status = SFU_IMG_TriggerImageInstallation(m_DwlSlotToInstall); + } + + if (SFU_SUCCESS == e_ret_status) + { + /* + * The FW installation succeeded: the previous FW is now backed up in the dwl slot. + * Nothing more to do, in the next FSM state we are going to verify the FW again and execute it if possible. + */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t FW installation succeeded."); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + else + { + /* + * The FW installation failed: we need to reboot and the resume procedure will be triggered at next boot. + * Nothing more to do, the next FSM state (HANDLE_CRITICAL_FAILURE) will deal with it. + */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t FW installation failed!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + + /* Installation successful : reboot for next operations on other slots + - installation + - resume + - rollback */ + if (SFU_SUCCESS == e_ret_status) + { + SFU_BOOT_ForceReboot(); + } + else + { + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + } +} + +/** + * @brief Execute a UserApp Fw installation resume + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_ResumeInstallNewUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + TRACE("\r\n= [SBOOT] STATE: RESUME INSTALLATION OF NEW USER FIRMWARE"); + + /* + * This resume installation procedure continue installation of new User FW in the active slot + */ + e_ret_status = SFU_IMG_TriggerResumeInstallation(m_ActiveSlotToResume, m_DwlSlotToInstall); + + /* Installation successful : reboot for next operations on other slots + - installation + - resume + - rollback */ + if (SFU_SUCCESS == e_ret_status) + { + SFU_BOOT_ForceReboot(); + } + else + { + /* No specific error cause managed here because the FSM state already provides the information. */ + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + } +} + +/** + * @brief Execute a rollback to the previous UserApp Fw + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_RollbackInstallPrevUserFw(void) +{ +#if defined(ENABLE_IMAGE_STATE_HANDLING) && !defined(SFU_NO_SWAP) + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + TRACE("\r\n= [SBOOT] STATE: ROLLBACK INSTALLATION TO PREVIOUS USER FIRMWARE"); + + /* + * Rollack installation to the previous User FW from Dwl_Slot + */ + e_ret_status = SFU_IMG_TriggerRollbackInstallation(m_ActiveSlotToRollback, m_DwlSlotToInstall); + + /* Installation successful : reboot for next operations on other slots + - installation + - resume + - rollback */ + if (SFU_SUCCESS == e_ret_status) + { + SFU_BOOT_ForceReboot(); + } + else + { + /* No specific error cause managed here because the FSM state already provides the information. */ + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + } +#else + TRACE("\r\n= [SBOOT] STATE: ROLLBACK NOT SUPPORTED"); + + /* No specific error cause managed here because the FSM state already provides the information. */ + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); +#endif /* ENABLE_IMAGE_STATE_HANDLING && !(SFU_NO_SWAP) */ +} + + +/** + * @brief Verify the UserApp Fw signature before executing it + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_VerifyUserFwSignature(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t i; + + TRACE("\r\n= [SBOOT] STATE: VERIFY USER FW SIGNATURE"); + + /* Double security check : + - testing "static protections" twice will avoid basic hardware attack + - flow control reached : dynamic protections checked + - re-execute static then dynamic check + - errors caught by FLOW_CONTROL ==> infinite loop */ + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); + FLOW_CONTROL_INIT(uFlowProtectValue, FLOW_CTRL_INIT_VALUE); + e_ret_status = SFU_LL_SECU_CheckApplyStaticProtections(); + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_STATIC_PROTECT); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_SECU_CheckApplyRuntimeProtections(SFU_THIRD_CONFIGURATION); + } + FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT); + if (e_ret_status != SFU_SUCCESS) + { + /* + * Due to previous flow control, we should never reach this code : + * Critical failure management if installation failed + */ + SFU_SET_SM_CURR_STATE(SFU_STATE_HANDLE_CRITICAL_FAILURE); + return; + } + + /* + * With the 2 images handling: + * 1. the header signature is verified when installing a new firmware + * 2. the firmware signature is checked when installing a new firmware + * 3. remaining part of active slot is kept "clean" during installation procedure + * So following checks should never fail. + */ + /* Check all active slots configured */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + /* FW installed ? */ + if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) + { + /* Initialize Flow control */ + FLOW_CONTROL_INIT(uFlowCryptoValue, FLOW_CTRL_INIT_VALUE); + + /* Check the header signature */ + e_ret_status = SFU_IMG_VerifyActiveImgMetadata(SLOT_ACTIVE_1 + i); + if (SFU_SUCCESS == e_ret_status) + { + /* Check the FW signature */ + e_ret_status = SFU_IMG_VerifyActiveImg(SLOT_ACTIVE_1 + i); + if (SFU_SUCCESS == e_ret_status) + { + /* Verify that there is no additional code beyond firmware image */ + e_ret_status = SFU_IMG_VerifyActiveSlot(SLOT_ACTIVE_1 + i); + if (SFU_SUCCESS != e_ret_status) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Unexpected code beyond FW image in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Firmware signature verification failure in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Header signature verification failure in slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + /* + * One of the checks fails : + * - Header signature + * - FW signature + * - No malicious code + * ==> Active slot should be invalidated + */ + if (SFU_SUCCESS != e_ret_status) + { + /* + * We should never reach this code. + * Could come from an attack ==> as an example we invalidate current firmware. + */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Erasing slot SLOT_ACTIVE_%d", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ + } + else + { + /* Verify if authentication and integrity controls performed */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); + } + } + else + { + if (SFU_IMG_VerifyEmptyActiveSlot(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* + * We should never reach this code. + * Could come from an attack ==> as an example we invalidate current firmware. + */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Slot SLOT_ACTIVE_%d not empty : erasing ...", SLOT_ACTIVE_1 + i); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + (void)SFU_IMG_InvalidateCurrentFirmware(SLOT_ACTIVE_1 + i); /* If this fails we continue anyhow */ + } + } + } + } + + /* Set the next State Machine state according to the success of the failure of e_ret_status */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_EXECUTE_USER_FW, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} + +/** + * @brief Exit from the SB/SFU State Machine and try to execute the UserApp Fw + * @param None + * @note This function must set the next State Machine State + * @retval None + */ +static void SFU_BOOT_SM_ExecuteUserFw(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status = SE_KO; + uint32_t i; + + TRACE("\r\n= [SBOOT] STATE: EXECUTE USER FIRMWARE"); + + /* Reload Watchdog */ + (void) SFU_LL_SECU_IWDG_Refresh(); + + /* Verify if authentication and integrity controls performed at SFU_STATE_VERIFY_USER_FW_SIGNATURE */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); + + /* Double security check for all active slots : + - Control twice the Header signature will avoid basic hardware attack + - Control twice the FW signature will avoid basic hardware attack */ + + /* Check all active slots configured */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + /* FW installed ? */ + if (SFU_SUCCESS == SFU_IMG_DetectFW(SLOT_ACTIVE_1 + i)) + { + /* Initialize Flow control */ + FLOW_CONTROL_INIT(uFlowCryptoValue, FLOW_CTRL_INIT_VALUE); + + /* Check the header signature */ + if (SFU_IMG_VerifyActiveImgMetadata(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } + + /* Check the FW signature */ + if (SFU_IMG_ControlActiveImgTag(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } + +#if defined(ENABLE_IMAGE_STATE_HANDLING) && !defined(SFU_NO_SWAP) + /* Move the state to SELFTEST for the new images */ + if (SFU_IMG_UpdateImageState(SLOT_ACTIVE_1 + i) != SFU_SUCCESS) + { + /* Image state cannot be changed : What to do ? + ==> decision to continue execution */ + TRACE("\r\n= [FWIMG] WARNING: IMAGE STATE CANNOT BE CHANGED!"); + } +#endif /* ENABLE_IMAGE_STATE_HANDLING && !(SFU_NO_SWAP) */ + + /* Verify if authentication and integrity controls performed */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_INTEGRITY); + } + } + } + + /* + * You may decide to implement additional checks before running the Firmware. + * For the time being we launch the FW present in the active slot. + * + * The bootloader must also take care of the security aspects: + * A.configure (if any) the external flash in execution mode with On The Fly DECryption (OTFDEC) + * B.lock the SE services the UserApp is not allowed to call + * C.leave secure boot mode + */ + + /* Configure active slot in execution mode with OTFDEC (if any) : required in case of external flash */ + e_ret_status = SFU_LL_FLASH_Config_Exe(m_ActiveSlotToExecute); + if (e_ret_status != SFU_SUCCESS) + { + /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_FLASH_CFG_ERR); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Lock part of Secure Engine services */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* Double instruction to avoid basic fault injection */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* De-initialize the SB_SFU bootloader before launching the UserApp */ + (void)SFU_BOOT_DeInit(); /* the return value is not checked, we will always try launching the UserApp */ + + /* Last flow control : lock service */ + FLOW_CONTROL_STEP(uFlowCryptoValue, FLOW_STEP_LOCK_SERVICE, FLOW_CTRL_LOCK_SERVICE); + + /* This function should not return */ + e_ret_status = SFU_IMG_LaunchActiveImg(m_ActiveSlotToExecute); + + /* This point should not be reached */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + /* We do not memorize any specific error, the FSM state is already providing the info */ + TRACE("\r\n\t SFU_IMG_LaunchActiveImg(SLOT_ACTIVE_%d) failure!", m_ActiveSlotToExecute); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + while (1 == 1) + { + ; /* wait for watchdog */ + } + } + else + { + /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_LOCK_SE_SERVICES_ERR); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + } + } + else + { + /* Set the error before forcing a reboot, don't care of return value as followed by reboot */ + SFU_EXCPT_SetError(SFU_EXCPT_LOCK_SE_SERVICES_ERR); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); + } + } + + /* This is unreachable code (dead code) in principle... + At this point we should not be able to reach the following instructions. + If we can execute them a critical issue has occurred.. So set the next State Machine accordingly */ + SFU_SET_SM_IF_CURR_STATE(e_ret_status, SFU_STATE_HANDLE_CRITICAL_FAILURE, SFU_STATE_HANDLE_CRITICAL_FAILURE); +} + +/** + * @brief Manage a Critical Failure occurred during the evolution of the State Machine + * @param None + * @note After a Critical Failure a Reboot will be called. + * @retval None + */ +static void SFU_BOOT_SM_HandleCriticalFailure(void) +{ + TRACE("\r\n= [SBOOT] STATE: HANDLE CRITICAL FAILURE"); + + /* It's not possible to continue without compromising the stability or the security of the solution. + The State Machine needs to be aborted and a Reset must be triggered */ + SFU_SET_SM_IF_CURR_STATE(SFU_ERROR, SFU_STATE_REBOOT_STATE_MACHINE, SFU_STATE_REBOOT_STATE_MACHINE); +} + +/** + * @brief The state machine is aborted and a Reset is triggered + * @param None + * @note You are in this condition because it's not possible to continue without + compromising the stability or the security of the solution. + * @retval None + */ +static void SFU_BOOT_SM_RebootStateMachine(void) +{ + TRACE("\r\n= [SBOOT] STATE: REBOOT STATE MACHINE"); + + /* + * In case some clean-up must be done before resetting. + * Please note that at the moment this function does not clean-up the RAM used by SB_SFU. + */ + (void)SFU_BOOT_DeInit(); + + /* This is the last operation executed. Force a System Reset */ + SFU_BOOT_ForceReboot(); +} + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * @brief Jump into standalone loader + * @param None + * @retval None + */ +static SFU_ErrorStatus SFU_BOOT_LaunchStandaloneLoader(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status = SE_KO; + uint32_t jump_address ; + typedef void (*Function_Pointer)(void); + Function_Pointer p_jump_to_function; + + + /* Lock part of Secure Engine services */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* Lock part of Secure Engine services */ + if (SE_LockRestrictServices(&e_se_status) == SE_SUCCESS) + { + /* Give execution rights to standalone loader */ + e_ret_status = SFU_LL_SECU_SetProtectionMPU_StandaloneLoader(); + } + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Initialize address to jump */ + jump_address = *(__IO uint32_t *)(((uint32_t)LOADER_REGION_ROM_START + 4)); + p_jump_to_function = (Function_Pointer) jump_address; + + /* Initialize loader's Stack Pointer */ + __set_MSP(*(__IO uint32_t *)(LOADER_REGION_ROM_START)); + + /* Jump into loader */ + p_jump_to_function(); + } + + /* The point below should NOT be reached */ + return e_ret_status; +} +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + +/** + * @brief Check (and Apply when possible) the security/safety/integrity protections. + * The "Apply" part depends on @ref SECBOOT_OB_DEV_MODE and @ref SFU_PROTECT_RDP_LEVEL. + * @param None + * @note This operation should be done as soon as possible after a reboot. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_CheckApplySecurityProtections(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Apply Static protections involving Option Bytes */ + if (SFU_LL_SECU_CheckApplyStaticProtections() == SFU_SUCCESS) + { + /* Apply runtime protections needed to be enabled after each Reset */ + e_ret_status = SFU_LL_SECU_CheckApplyRuntimeProtections(SFU_INITIAL_CONFIGURATION); + } + + return e_ret_status; +} + +/** + * @brief System security configuration + * @param None + * @note Check and apply the security protections. This has to be done as soon + * as possible after a reset + * @retval None + */ +static SFU_ErrorStatus SFU_BOOT_SystemSecurity_Config(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + /* WARNING: The following CheckApplySecurityProtection function must be called + as soon as possible after a Reset in order to be sure the system is secured + before starting any other operation. The drawback is that the ErrorManagement + is not initialized yet, so in case of failure of this function, there will not be + any error stored into the BootInfo or other visible effects. */ + + /* Very few things are already initialized at this stage. Need additional initialization + to show a message that is added as below only in Debug/Test mode */ +#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) + (void) SFU_COM_Init(); +#endif /* SFU_DEBUG_MODE || SFU_TEST_PROTECTION */ + + if (SFU_BOOT_CheckApplySecurityProtections() != SFU_SUCCESS) + { + /* WARNING: This might be generated by an attempted attack or a bug of your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + TRACE("\r\n= [SBOOT] System Security Check failed! Rebooting..."); + } + else + { + TRACE("\r\n= [SBOOT] System Security Check successfully passed. Starting..."); + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief Periodic verification of applied protection mechanisms, in order to prevent + * a malicious code removing some of the applied security/integrity features. + * The IWDG is also refreshed in this function. + * @param None + * @note This function must be called with a frequency greater than 0.25Hz! + * Otherwise a Reset will occur. Once enabled the IWDG cannot be disabled + * So the User App should continue to refresh the IWDG counter. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_BOOT_SecuritySafetyCheck(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Refresh the IWDG */ + e_ret_status = SFU_LL_SECU_IWDG_Refresh(); + + + /* Add your code here for customization: + e.g. for additional security or safety periodic check. + ... + ... + */ + return e_ret_status; +} + +/** + * @brief Manage the the Reset sources, and if the case store the error for the next steps + * @param None + * @retval None + */ +static void SFU_BOOT_ManageResetSources(void) +{ + SFU_RESET_IdTypeDef e_wakeup_source_id = SFU_RESET_UNKNOWN; + + /* Check the wakeup sources */ + SFU_LL_SECU_GetResetSources(&e_wakeup_source_id); + switch (e_wakeup_source_id) + { + /* + * Please note that the example of reset causes handling below is only a basic example to illustrate the way the + * RCC_CSR flags can be used to do so. + */ + + case SFU_RESET_WDG_RESET: + TRACE("\r\n\t WARNING: A Reboot has been triggered by a Watchdog reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_LOW_POWER: + TRACE("\r\n\t INFO: A Reboot has been triggered by a LowPower reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_HW_RESET: + TRACE("\r\n\t INFO: A Reboot has been triggered by a Hardware reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_BOR_RESET: + TRACE("\r\n\t INFO: A Reboot has been triggered by a BOR reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_SW_RESET: + TRACE("\r\n\t INFO: A Reboot has been triggered by a Software reset!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + case SFU_RESET_OB_LOADER: + TRACE("\r\n\t WARNING: A Reboot has been triggered by an Option Bytes reload!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + + default: + TRACE("\r\n\t WARNING: A Reboot has been triggered by an Unknown reset source!"); + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system, or simply discard it if this is expected. + ... + ... + */ + break; + } + + /* Once the reset sources has been managed and a possible error has been set, clear the reset sources */ + SFU_LL_SECU_ClearResetSources(); +} + +/** + * @brief Implement the Cube_Hal Callback generated on the Tamper IRQ. + * @param None + * @retval None + */ +void SFU_CALLBACK_ANTITAMPER(RTC_HandleTypeDef *hrtc) +{ + UNUSED(hrtc); + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_TAMPERING_FAULT); +} + +/** + * @brief Implement the Cube_Hal Callback generated on the Memory Fault. + * @note After a Memory Fault could not be possible to execute additional code + * @param None + * @retval None + */ +void SFU_CALLBACK_MEMORYFAULT(void) +{ + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_MEMORY_FAULT); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_boot.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_boot.h new file mode 100644 index 00000000..45d6ca7d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_boot.h @@ -0,0 +1,205 @@ +/** + ****************************************************************************** + * @file sfu_boot.h + * @author MCD Application Team + * @brief Header the Secure Boot module, part of the SFU-En project (SB/SFU). + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_BOOT_H +#define SFU_BOOT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief SFU_BOOT Init Error Type Definition + */ +typedef enum +{ + SFU_BOOT_SECENG_INIT_FAIL, /*!< failure at secure engine initialization stage */ + SFU_BOOT_SECIPS_CFG_FAIL, /*!< failure when configuring the security IPs */ + SFU_BOOT_INIT_FAIL, /*!< failure when initializing the secure boot service */ + SFU_BOOT_INIT_ERROR /*!< Service cannot start: unspecified error */ +} SFU_BOOT_InitErrorTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/** + * @brief SFU_BOOT Flow Control : Initial value + */ +#define FLOW_CTRL_INIT_VALUE 0x00005776U /*!< Init value definition */ + +/** + * @brief SFU_BOOT Flow Control : Steps definition + */ +#define FLOW_STEP_UBE 0x00006787U /*!< Step UBE value */ +#define FLOW_STEP_AUTHENTICATE 0x00007999U /*!< Step AUTHENTICATE value */ +#define FLOW_STEP_INTEGRITY 0x0000aab5U /*!< Step INTEGRITY value */ +#define FLOW_STEP_LOCK_SERVICE 0x0000b4abU /*!< Step LOCK SERVICE value */ + +#ifdef SFU_WRP_PROTECT_ENABLE +#define FLOW_STEP_WRP 0x0000cccdU /*!< Step WRP value */ +#else +#define FLOW_STEP_WRP 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_WRP_PROTECT_ENABLE */ + +#ifdef SFU_PCROP_PROTECT_ENABLE +#define FLOW_STEP_PCROP 0x0000d2d3U /*!< Step PCROP value */ +#else +#define FLOW_STEP_PCROP 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_PCROP_PROTECT_ENABLE */ + +#ifdef SFU_RDP_PROTECT_ENABLE +#define FLOW_STEP_RDP 0x0000e3dcU /*!< Step RDP value */ +#else +#define FLOW_STEP_RDP 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_RDP_PROTECT_ENABLE */ + +#ifdef SFU_SECURE_USER_PROTECT_ENABLE +#define FLOW_STEP_SEC_MEM 0x0000fdc2U /*!< Step SECURE MEMORY value */ +#else +#define FLOW_STEP_SEC_MEM 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_SECURE_USER_PROTECT_ENABLE */ + +#ifdef SFU_TAMPER_PROTECT_ENABLE +#define FLOW_STEP_TAMPER 0x00012cd3U /*!< Step TAMPER value */ +#else +#define FLOW_STEP_TAMPER 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + +#ifdef SFU_MPU_PROTECT_ENABLE +#define FLOW_STEP_MPU 0x000132cdU /*!< Step MPU value */ +#else +#define FLOW_STEP_MPU 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_MPU_PROTECT_ENABLE */ + +#ifdef SFU_FWALL_PROTECT_ENABLE +#define FLOW_STEP_FWALL 0x00014aabU /*!< Step FWALL value */ +#else +#define FLOW_STEP_FWALL 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_FWALL_PROTECT_ENABLE */ + +#ifdef SFU_DMA_PROTECT_ENABLE +#define FLOW_STEP_DMA 0x000154b5U /*!< Step DMA value */ +#else +#define FLOW_STEP_DMA 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_DMA_PROTECT_ENABLE */ + +#ifdef SFU_IWDG_PROTECT_ENABLE +#define FLOW_STEP_IWDG 0x000165baU /*!< Step IWDG value */ +#else +#define FLOW_STEP_IWDG 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_IWDG_PROTECT_ENABLE */ + +#ifdef SFU_DAP_PROTECT_ENABLE +#define FLOW_STEP_DAP 0x00017ba4U /*!< Step DAP value */ +#else +#define FLOW_STEP_DAP 0x00000000U /*!< No effect on control flow */ +#endif /* SFU_DAP_PROTECT_ENABLE */ + +/** + * @brief SFU_BOOT Flow Control : Control values static protections + */ +#define FLOW_CTRL_UBE (FLOW_CTRL_INIT_VALUE ^ FLOW_STEP_UBE) +#define FLOW_CTRL_WRP (FLOW_CTRL_UBE ^ FLOW_STEP_WRP) +#define FLOW_CTRL_PCROP (FLOW_CTRL_WRP ^ FLOW_STEP_PCROP) +#define FLOW_CTRL_SEC_MEM (FLOW_CTRL_PCROP ^ FLOW_STEP_SEC_MEM) +#define FLOW_CTRL_RDP (FLOW_CTRL_SEC_MEM ^ FLOW_STEP_RDP) +#define FLOW_CTRL_STATIC_PROTECT FLOW_CTRL_RDP + +/** + * @brief SFU_BOOT Flow Control : Control values runtime protections + */ +#define FLOW_CTRL_MPU (FLOW_CTRL_STATIC_PROTECT ^ FLOW_STEP_MPU) +#define FLOW_CTRL_FWALL (FLOW_CTRL_MPU ^ FLOW_STEP_FWALL) +#define FLOW_CTRL_DMA (FLOW_CTRL_FWALL ^ FLOW_STEP_DMA) +#define FLOW_CTRL_IWDG (FLOW_CTRL_DMA ^ FLOW_STEP_IWDG) +#define FLOW_CTRL_DAP (FLOW_CTRL_IWDG ^ FLOW_STEP_DAP) +#define FLOW_CTRL_TAMPER (FLOW_CTRL_DAP ^ FLOW_STEP_TAMPER) +#define FLOW_CTRL_RUNTIME_PROTECT FLOW_CTRL_TAMPER + +/** + * @brief SFU_BOOT Flow Control : Control values crypto operations + */ +#define FLOW_CTRL_AUTHENTICATE (FLOW_CTRL_INIT_VALUE ^ FLOW_STEP_AUTHENTICATE) +#define FLOW_CTRL_INTEGRITY (FLOW_CTRL_AUTHENTICATE ^ FLOW_STEP_INTEGRITY) +#define FLOW_CTRL_LOCK_SERVICE (FLOW_CTRL_INTEGRITY ^ FLOW_STEP_LOCK_SERVICE) + +/* External variables --------------------------------------------------------*/ +/** + * Flow control initial values. + * - Security protections flow (static + dynamic) + * - Crypto operations flow (authentication, integrity) + */ +extern uint32_t uFlowProtectValue; +extern uint32_t uFlowCryptoValue; + +/* Exported macros -----------------------------------------------------------*/ +/** Control with STEP operation : + * (uFlowValue XOR STEP_VALUE) should be equal to CTRL_VALUE ==> execution stopped if failed ! + */ +#define FLOW_CONTROL_STEP(C,B,A) \ + do{ \ + (C) ^= (B);\ + if ((C) != (A))\ + { \ + SFU_EXCPT_Security_Error();\ + } \ + }while(0) + +/** Control without STEP operation : + * uFlowValue should be equal to CTRL_VALUE ==> execution stopped if failed ! + */ +#define FLOW_CONTROL_CHECK(B,A) \ + do{ \ + if ((B) != (A))\ + { \ + SFU_EXCPT_Security_Error();\ + } \ + }while(0) + +/** Control flow initialization + */ +#define FLOW_CONTROL_INIT(B,A) \ + do{ \ + (B) = (A);\ + }while(0) + +/** STEP update only : + * (uFlowValue XOR STEP_VALUE) + */ +#define FLOW_STEP(B,A) \ + do{ \ + (B) ^= (A);\ + }while(0) + + +/* Exported functions ------------------------------------------------------- */ +SFU_BOOT_InitErrorTypeDef SFU_BOOT_RunSecureBootService(void); +void SFU_BOOT_ForceReboot(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_BOOT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_loader.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_loader.c new file mode 100644 index 00000000..f7599f7b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_loader.c @@ -0,0 +1,544 @@ +/** + ****************************************************************************** + * @file sfu_com_loader.c + * @author MCD Application Team + * @brief Secure Firmware Update COM module. + * This file provides set of firmware functions to manage SFU Com + * functionalities for the local loader. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level.h" +#include "sfu_low_level_security.h" +#include "sfu_com_loader.h" +#include "sfu_trace.h" + + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_TEST_PROTECTION) + +/* Private defines -----------------------------------------------------------*/ +#if defined(__ICCARM__) +#define PUTCHAR_PROTOTYPE int putchar(int ch) +#elif defined(__ARMCC_VERSION) +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#elif defined(__GNUC__) +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#endif /* __ICCARM__ */ + +#define SFU_COM_LOADER_TIME_OUT ((uint32_t )0x800U) /*!< COM Transmit and Receive Timeout*/ +#define SFU_COM_LOADER_SERIAL_TIME_OUT ((uint32_t )100U) /*!< Serial PutByte and PutString Timeout*/ + +/* Private macros ------------------------------------------------------------*/ +#define IS_CAP_LETTER(c) (((c) >= (uint8_t) 'A') && ((c) <= (uint8_t) 'F')) +#define IS_LC_LETTER(c) (((c) >= (uint8_t) 'a') && ((c) <= (uint8_t) 'f')) +#define IS_09(c) (((c) >= (uint8_t) '0') && ((c) <= (uint8_t) '9')) +#define ISVALIDHEX(c) (IS_CAP_LETTER(c) || IS_LC_LETTER(c) || IS_09(c)) +#define ISVALIDDEC(c) IS_09(c) +#define CONVERTDEC(c) ((c) - (uint8_t) '0') + +#define CONVERTHEX_ALPHA(c) (IS_CAP_LETTER(c) ? ((c) - (uint8_t) 'A' + 10U) : ((c) - (uint8_t) 'a' + 10U)) +#define CONVERTHEX(c) (IS_09(c) ? ((c) - (uint8_t) '0') : CONVERTHEX_ALPHA(c)) + +/* Private function prototypes -----------------------------------------------*/ +static HAL_StatusTypeDef ReceivePacket(uint8_t *pData, uint32_t *puLength, uint32_t uTimeOut); +static uint32_t Str2Int(uint8_t *pInputStr, uint32_t *pIntNum); + +/* Functions Definition ------------------------------------------------------*/ + +#if !defined(SFU_DEBUG_MODE) && !defined(SFU_TEST_PROTECTION) +/** + * @brief SFU Com Init function. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_Init(void) +{ +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) + setvbuf(stdout, NULL, _IONBF, 0); +#endif /* __GNUC__ */ + return SFU_LL_UART_Init(); +} + +/** + * @brief SFU Com DeInit function. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_DeInit(void) +{ + return SFU_LL_UART_DeInit(); +} + +#endif /* !SFU_DEBUG_MODE && !SFU_TEST_PROTECTION */ + +/** + * @brief Receive a file using the ymodem protocol with SFU_COM_YMODEM_CRC16. + * @param peCOMStatus: SFU_COM_YMODEM_StatusTypeDef result of reception/programming. + * @param puSize: size of received file. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise + */ +SFU_ErrorStatus SFU_COM_YMODEM_Receive(SFU_COM_YMODEM_StatusTypeDef *peCOMStatus, uint32_t *puSize) +{ + uint32_t i; + uint32_t packet_length = 0U; + uint32_t session_done = 0U; + uint32_t file_done; + uint32_t errors = 0U; + uint32_t session_begin = 0U; + uint32_t filesize = 0U; + uint32_t packets_received; + uint8_t *file_ptr; + uint8_t file_size[SFU_COM_YMODEM_FILE_SIZE_LENGTH + 1U]; + uint8_t tmp; + static uint8_t m_aPacketData[SFU_COM_YMODEM_PACKET_1K_SIZE + SFU_COM_YMODEM_PACKET_DATA_INDEX + + SFU_COM_YMODEM_PACKET_TRAILER_SIZE] __attribute__((aligned(8))); + + /* Check the pointers allocation */ + if ((peCOMStatus == NULL) || (puSize == NULL)) + { + return SFU_ERROR; + } + + *peCOMStatus = SFU_COM_YMODEM_OK; + + while ((session_done == 0U) && (*peCOMStatus == SFU_COM_YMODEM_OK)) + { + packets_received = 0U; + file_done = 0U; + while ((file_done == 0U) && (*peCOMStatus == SFU_COM_YMODEM_OK)) + { + switch (ReceivePacket(m_aPacketData, &packet_length, SFU_COM_YMODEM_DOWNLOAD_TIMEOUT)) + { + case HAL_OK: + errors = 0U; + switch (packet_length) + { + case 3U: + /* Startup sequence */ + break; + case 2U: + /* Abort by sender */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + *peCOMStatus = SFU_COM_YMODEM_ABORT; + break; + case 0U: + /* End of transmission */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + *puSize = filesize; + file_done = 1U; + break; + default: + /* Normal packet */ + if (m_aPacketData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX] != (packets_received & 0x000000FFU)) + { + /* No NACK sent for a better synchro with remote : packet will be repeated */ + } + else + { + if (packets_received == 0U) + { + /* File name packet */ + if (m_aPacketData[SFU_COM_YMODEM_PACKET_DATA_INDEX] != 0U) + { + /* File name skipped */ + i = 0U; + file_ptr = m_aPacketData + SFU_COM_YMODEM_PACKET_DATA_INDEX; + while ((*file_ptr != 0U) && (i < SFU_COM_YMODEM_FILE_NAME_LENGTH)) + { + i++; + file_ptr++; + } + /* end of file name ('\0') skipped */ + file_ptr++; + + /* File size extraction */ + i = 0U; + while ((*file_ptr != (uint8_t) ' ') && (i < SFU_COM_YMODEM_FILE_SIZE_LENGTH)) + { + file_size[i] = *file_ptr; + i++; + file_ptr++; + } + file_size[i] = (uint8_t) '\0'; + (void) Str2Int(file_size, &filesize); + + /* Header packet received callback call*/ + if (SFU_COM_YMODEM_HeaderPktRxCpltCallback((uint32_t) filesize) == SFU_SUCCESS) + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + (void) SFU_LL_UART_Flush(); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CRC16); + } + else + { + /* End session */ + tmp = SFU_COM_YMODEM_CA; + (void) SFU_LL_UART_Transmit(&tmp, 1U, SFU_COM_YMODEM_NAK_TIMEOUT); + (void) SFU_LL_UART_Transmit(&tmp, 1U, SFU_COM_YMODEM_NAK_TIMEOUT); + return SFU_ERROR; + } + } + /* File header packet is empty, end session */ + else + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + file_done = 1U; + session_done = 1U; + break; + } + } + else /* Data packet */ + { + /* Data packet received callback call*/ + if (SFU_COM_YMODEM_DataPktRxCpltCallback(&m_aPacketData[SFU_COM_YMODEM_PACKET_DATA_INDEX], + packet_length) == SFU_SUCCESS) + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_ACK); + + } + else /* An error occurred while writing to Flash memory */ + { + /* End session */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + *peCOMStatus = SFU_COM_YMODEM_DATA; + } + + } + packets_received ++; + session_begin = 1; + } + break; + } + break; + case HAL_BUSY: /* Abort actually */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + *peCOMStatus = SFU_COM_YMODEM_ABORT; + break; + default: + if (session_begin > 0U) + { + errors ++; + } + if (errors > SFU_COM_YMODEM_MAX_ERRORS) + { + /* Abort communication */ + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CA); + *peCOMStatus = SFU_COM_YMODEM_ABORT; + } + else + { + (void) SFU_COM_Serial_PutByte(SFU_COM_YMODEM_CRC16); /* Ask for a packet */ +#ifndef MINICOM_YMODEM + /* Minicom does not accept this extra character */ + TRACE("\b."); /* Replace C char by . on display console */ +#endif /* MINICOM_YMODEM */ + /* + * Toggling the LED in case no console is available: the toggling frequency depends on + * SFU_COM_YMODEM_DOWNLOAD_TIMEOUT + */ + (void) BSP_LED_Toggle(SFU_STATUS_LED); + } + break; + } + } + } + /* Make sure the status LED is turned off */ + (void) BSP_LED_Off(SFU_STATUS_LED); + + if (*peCOMStatus == SFU_COM_YMODEM_OK) + { + return SFU_SUCCESS; + } + else + { + return SFU_ERROR; + } +} + +/** + * @brief Transmit a byte to the COM Port. + * @param uParam: The byte to be sent. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_Serial_PutByte(uint8_t uParam) +{ + return SFU_LL_UART_Transmit(&uParam, 1U, SFU_COM_LOADER_SERIAL_TIME_OUT); +} + +/** + * @brief Convert a string to an integer. + * @param pInputStr: The string to be converted. + * @param pIntNum: The integer value. + * @retval 1: Correct + * 0: Error + */ +static uint32_t Str2Int(uint8_t *pInputStr, uint32_t *pIntNum) +{ + uint32_t i = 0U; + uint32_t res = 0U; + uint32_t val = 0U; + uint8_t digit; + + if ((pInputStr[0] == (uint8_t)'0') && ((pInputStr[1] == (uint8_t)'x') || (pInputStr[1] == (uint8_t)'X'))) + { + i = 2U; + while ((i < 11U) && (pInputStr[i] != (uint8_t)'\0')) + { + if (ISVALIDHEX(pInputStr[i])) + { + digit = CONVERTHEX(pInputStr[i]); + val = (val << 4U) + digit; + } + else + { + /* Return 0, Invalid input */ + res = 0U; + break; + } + i++; + } + + /* valid result */ + if (pInputStr[i] == (uint8_t)'\0') + { + *pIntNum = val; + res = 1U; + } + } + else /* max 10-digit decimal input */ + { + while ((i < 11U) && (res != 1U)) + { + if (pInputStr[i] == (uint8_t)'\0') + { + *pIntNum = val; + /* return 1 */ + res = 1U; + } + else if (((pInputStr[i] == (uint8_t)'k') || (pInputStr[i] == (uint8_t)'K')) && (i > 0U)) + { + val = val << 10U; + *pIntNum = val; + res = 1U; + } + else if (((pInputStr[i] == (uint8_t)'m') || (pInputStr[i] == (uint8_t)'M')) && (i > 0U)) + { + val = val << 20U; + *pIntNum = val; + res = 1U; + } + else if (ISVALIDDEC(pInputStr[i])) + { + digit = CONVERTDEC(pInputStr[i]); + val = (val * 10U) + digit; + } + else + { + /* return 0, Invalid input */ + res = 0U; + break; + } + i++; + } + } + + return res; +} + +/** + * @brief Receive a packet from sender + * @param pData: pointer to received data. + * @param puLength + * 0: end of transmission + * 2: abort by sender + * >0: packet length + * @param uTimeOut: receive timeout (ms). + * @retval HAL_OK: normally return + * HAL_BUSY: abort by user + */ +static HAL_StatusTypeDef ReceivePacket(uint8_t *pData, uint32_t *puLength, uint32_t uTimeout) +{ + uint32_t crc; + uint32_t packet_size = 0U; + HAL_StatusTypeDef status; + SFU_ErrorStatus eRetStatus; + + uint8_t char1; + +#ifdef MINICOM_YMODEM + uint32_t myIdx = 0; /* index indicating where to write in pData */ +#endif /* MINICOM_YMODEM */ + + *puLength = 0U; + + /* This operation could last long. Need to refresh the Watchdog if enabled. It could be implemented as a callback*/ + (void) SFU_LL_SECU_IWDG_Refresh(); + + eRetStatus = SFU_LL_UART_Receive(&char1, 1, uTimeout); + + if (eRetStatus == SFU_SUCCESS) + { + status = HAL_OK; + + switch (char1) + { + case SFU_COM_YMODEM_SOH: + packet_size = SFU_COM_YMODEM_PACKET_SIZE; + break; + case SFU_COM_YMODEM_STX: + packet_size = SFU_COM_YMODEM_PACKET_1K_SIZE; + break; + case SFU_COM_YMODEM_EOT: + break; + case SFU_COM_YMODEM_CA: + if ((SFU_LL_UART_Receive(&char1, 1U, uTimeout) == SFU_SUCCESS) && (char1 == SFU_COM_YMODEM_CA)) + { + packet_size = 2U; + } + else + { + status = HAL_ERROR; + } + break; + case SFU_COM_YMODEM_ABORT1: + case SFU_COM_YMODEM_ABORT2: + status = HAL_BUSY; + break; + case SFU_COM_YMODEM_RB: + (void) SFU_LL_UART_Receive(&char1, 1U, uTimeout); /* Ymodem startup sequence : rb ==> 0x72 + 0x62 + 0x0D */ + (void) SFU_LL_UART_Receive(&char1, 1U, uTimeout); + packet_size = 3U; + break; + default: + status = HAL_ERROR; + break; + } + *pData = char1; + + if (packet_size >= SFU_COM_YMODEM_PACKET_SIZE) + { + +#ifndef MINICOM_YMODEM + eRetStatus = SFU_LL_UART_Receive(&pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX], + (uint16_t)(packet_size + SFU_COM_YMODEM_PACKET_OVERHEAD_SIZE), uTimeout); +#else + eRetStatus = SFU_SUCCESS; + /* Receive byte per byte until no data left or no space left in buffer */ + while ((SFU_SUCCESS == eRetStatus) && + ((myIdx + SFU_COM_YMODEM_PACKET_NUMBER_INDEX) < SFU_COM_YMODEM_PACKET_1K_SIZE + + SFU_COM_YMODEM_PACKET_DATA_INDEX + + SFU_COM_YMODEM_PACKET_TRAILER_SIZE) + ) + { + eRetStatus = SFU_LL_UART_Receive(&pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX + myIdx], + 1U, uTimeout); + myIdx++; + } + + if (myIdx > 1) + { + /* We received some bytes */ + eRetStatus = SFU_SUCCESS; + } +#endif /* MINICOM_YMODEM */ + + /* Simple packet sanity check */ + if (eRetStatus == SFU_SUCCESS) + { + status = HAL_OK; + + if (pData[SFU_COM_YMODEM_PACKET_NUMBER_INDEX] != ((pData[SFU_COM_YMODEM_PACKET_CNUMBER_INDEX]) ^ + SFU_COM_YMODEM_NEGATIVE_BYTE)) + { + packet_size = 0U; + status = HAL_ERROR; + } + else + { + /* Check packet CRC*/ + crc = (((uint32_t)pData[ packet_size + SFU_COM_YMODEM_PACKET_DATA_INDEX ]) << 8U) & 0x0000FF00U; + crc += pData[ packet_size + SFU_COM_YMODEM_PACKET_DATA_INDEX + 1U ]; + + /*Configure CRC with 16-bit polynomial*/ + if (SFU_LL_CRC_Config(SFU_CRC_CONFIG_16BIT) == SFU_SUCCESS) + { + if (SFU_LL_CRC_Calculate((uint32_t *)(uint32_t)&pData[SFU_COM_YMODEM_PACKET_DATA_INDEX], packet_size) != crc) + { + packet_size = 0U; + status = HAL_ERROR; + } + + } + else + { + packet_size = 0U; + status = HAL_ERROR; + } + } + } + else + { + status = HAL_ERROR; + } + } + } + else + { + status = HAL_ERROR; + } + + *puLength = packet_size; + return status; +} + +/** + * @brief Ymodem Header Packet Transfer completed callback. + * @param uFileSize: Dimension of the file that will be received. + * @retval None + */ +__weak SFU_ErrorStatus SFU_COM_YMODEM_HeaderPktRxCpltCallback(uint32_t uFileSize) +{ + + /* NOTE : This function should not be modified, when the callback is needed, + the SFU_COM_YMODEM_HeaderPktRxCpltCallback could be implemented in the user file + */ + UNUSED(uFileSize); + return SFU_SUCCESS; +} + +/** + * @brief Ymodem Data Packet Transfer completed callback. + * @param pData: Pointer to the buffer. + * @param uSize: Packet dimension. + * @retval None + */ +__weak SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) +{ + + /* NOTE : This function should not be modified, when the callback is needed, + the SFU_COM_YMODEM_DataPktRxCpltCallback could be implemented in the user file + */ + UNUSED(pData); + UNUSED(uSize); + return SFU_SUCCESS; +} + +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || defined(SFU_TEST_PROTECTION) */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM4/Inc/sfu_com_loader.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_loader.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM4/Inc/sfu_com_loader.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_loader.h diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/Common/sfu_com_trace.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_trace.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/Common/sfu_com_trace.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_trace.c diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/Common/sfu_com_trace.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_trace.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/Common/sfu_com_trace.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_com_trace.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_def.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_def.h new file mode 100644 index 00000000..78458507 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_def.h @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * @file sfu_def.h + * @author MCD Application Team + * @brief This file contains the general definitions for SBSFU application. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_DEF_H +#define SFU_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if defined(__ARMCC_VERSION) +#include "mapping_sbsfu.h" +#elif defined (__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __ARMCC_VERSION */ +#include "app_sfu.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief SFU Error Typedef + */ +typedef enum +{ + SFU_ERROR = 0x00001FE1U, + SFU_SUCCESS = 0x00122F11U +} SFU_ErrorStatus; + +/* Exported constants --------------------------------------------------------*/ + +#define SFU_RAM_BASE ((uint32_t) SE_REGION_RAM_START) +#define SFU_RAM_END ((uint32_t) SB_REGION_RAM_END) +#define SFU_SB_RAM_BASE ((uint32_t) SB_REGION_RAM_START) +#define SFU_SB_RAM_END ((uint32_t) SB_REGION_RAM_END) + + +#define SFU_BOOT_BASE_ADDR ((uint32_t) INTVECT_START) /* SFU Boot Address */ +#define SFU_ROM_ADDR_END ((uint32_t) SB_REGION_ROM_END) /* SBSFU end Address (covering all the SBSFU + executable code) */ + +#define SFU_SENG_ROM_ADDR_START ((uint32_t) SE_CODE_REGION_ROM_START)/* Secure Engine area address START */ +#define SFU_SENG_ROM_ADDR_END ((uint32_t) SE_CODE_REGION_ROM_END) /* Secure Engine area address END - SE includes + everything up to the License */ +#define SFU_SENG_ROM_SIZE ((uint32_t) (SFU_SENG_ROM_ADDR_END - \ + SFU_SENG_ROM_ADDR_START + 1U)) /* Secure Engine area size */ + +#define SFU_KEYS_ROM_ADDR_START ((uint32_t) SE_KEY_REGION_ROM_START) /* Keys Area (Keys + Keys Retrieve function) + START. This is the PCRoP Area */ +#define SFU_KEYS_ROM_ADDR_END ((uint32_t) SE_KEY_REGION_ROM_END) /* Keys Area (Keys + Keys Retrieve function) END. + This is the PCRoP Area */ + +#define SFU_SENG_RAM_ADDR_START ((uint32_t) SE_REGION_RAM_START) /* Secure Engine reserved RAM1 area START + address */ +#define SFU_SENG_RAM_ADDR_END ((uint32_t) SE_REGION_RAM_END) /* Secure Engine reserved RAM1 area END address */ +#define SFU_SENG_RAM_SIZE ((uint32_t) (SFU_SENG_RAM_ADDR_END - \ + SFU_SENG_RAM_ADDR_START + 1U)) /* Secure Engine reserved RAM area SIZE */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_DEF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_error.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_error.c new file mode 100644 index 00000000..69712062 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_error.c @@ -0,0 +1,236 @@ +/** + ****************************************************************************** + * @file sfu_error.c + * @author MCD Application Team + * @brief SFU ERROR + * This file provides set of firmware functions for SB_SFU errors handling. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_fsm_states.h" +#include "sfu_error.h" +#include "sfu_low_level_security.h" +#include "sfu_trace.h" +#include "se_interface_bootloader.h" +#include "sfu_fwimg_services.h" +#include "sfu_boot.h" +#include "sfu_test.h" + + +/* Private variables ---------------------------------------------------------*/ +#ifdef SFU_DEBUG_MODE +/** + * The following strings associated to the exceptions/errors are used for debugging purpose. + * WARNING: The string array must match perfectly with the @ref SFU_EXCPT_IdTypeDef. + * And the @ref SFU_EXCPT_IdTypeDef enum must be a sequence starting from 0 + */ +static char *m_aErrorStrings[] ={ "No error. Success", + "Memory fault", + "Hard fault", + "Tampering fault", + "SE lock cannot be set", +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + "Fw too big", + "File not correctly received", +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + "Fw header authentication error", + "Fw decryption error", + "Fw signature check error", + "Flash error", + "External flash configuration error.", + "Header erasing error", + "Header validation error", + "Additional code detected beyond FW", + "Error during swap process", + "Error during rollback process", + "Backed-up fw not identified", + "Backup copy error", + "Dwl slot erasing error", + "Trailer erasing error", + "Trailer update error", + "Magic tag update error", + "Fw version rejected (anti-rollback)", + "Unknown error" + }; + +#endif /* SFU_DEBUG_MODE */ + +/* Private function prototypes -----------------------------------------------*/ +static void SFU_EXCPT_RuntimeExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Print relevant errpr message. + * @param Error Error code. + * @retval None + */ +void SFU_EXCPT_SetError(SFU_EXCPT_IdTypeDef eExceptionId) +{ + if (eExceptionId <= SFU_EXCPT_UNKNOWN) + { +#ifdef SFU_DEBUG_MODE + TRACE("\r\n\t%s",m_aErrorStrings[(uint32_t) eExceptionId]); +#endif /* SFU_DEBUG_MODE */ + } +} + + +/** + * @brief Manage the Exception generated by an IRQ + * @param eExceptionId : Exception ID. + * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. + * @note Because of the interruption of the State Machine execution, + * it's not possible to continue without compromising the stability or + * the security of the solution. A System Reset is forced at the end. + * @retval None + */ +void SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId) +{ +#ifdef SFU_DEBUG_MODE + uint8_t message[150]; + uint32_t i = 0U; + + /* Avoid warning with cast frombetween char* and uint8_t* */ + while ((m_aErrorStrings[(uint32_t) eExceptionId][i] != 0u) && (i < 149U)) + { + message[i] = m_aErrorStrings[(uint32_t) eExceptionId][i]; + i++; + } + message[i] = 0U; + + /* Print relevant error message */ + TRACE_IRQ((uint8_t *)"\r\n\t "); + TRACE_IRQ(message); +#endif /* SFU_DEBUG_MODE */ + + /* Try to take an action */ + SFU_EXCPT_RuntimeExceptionHandler(eExceptionId); + + /* It's not possible to continue without compromising the stability or the security of the solution. + The State Machine needs to be aborted and a Reset must be triggered */ + SFU_BOOT_ForceReboot(); +} + +/** + * @brief Stop in case of security error + * @param eExceptionId : Exception ID. + * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ + +void SFU_EXCPT_Security_Error(void) +{ + TRACE("\r\n= [SBOOT] Security issue : execution stopped !"); + HAL_Delay(1000); + /* This is the last operation executed. Force a System Reset. */ + NVIC_SystemReset(); +} + +/** + * @brief SFU Exception Initialization. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_EXCPT_Init(void) +{ + SFU_ErrorStatus e_ret_status; + + /* ADD SRC CODE HERE + ... + */ + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} + +/** + * @brief SFU Exception DeInitialization. + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_EXCPT_DeInit(void) +{ + SFU_ErrorStatus e_ret_status; + /* ADD SRC CODE HERE + ... + */ + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} + +/** + * @brief Manage the Exception/Errors/Fault at runtime, when detected + * @param eExceptionId : Exception ID. + * This parameter can be a value of @ref SFU_EXCPT_ID_Structure_definition. + * @note A System Reset is forced at the end by the caller of this function. + * WARNING: Be aware that this function can be called by an IRQ while + * using the printf, since the printf is not a reentrant function, and using + * the printf inside this function as well, a fault will likely occur. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static void SFU_EXCPT_RuntimeExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId) +{ + switch (eExceptionId) + { + case SFU_EXCPT_TAMPERING_FAULT: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ + break; + + case SFU_EXCPT_MEMORY_FAULT: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ + break; + + case SFU_EXCPT_HARD_FAULT: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ +#ifdef SFU_TEST_PROTECTION + /* On STM32WLXX : Hard fault IT is generated instead of memory fault when MPU accessed + ==> this is not an error */ +#endif /* SFU_TEST_PROTECTION */ + break; + + default: + /* WARNING: This might be generated by an attempted attack, a bug or your code! + Add your code here in order to implement a custom action for this event, + e.g. trigger a mass erase or take any other action in order to + protect your system. + ... + ... + */ + break; + } + +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_error.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_error.h new file mode 100644 index 00000000..6506d102 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_error.h @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * @file sfu_error.h + * @author MCD Application Team + * @brief This file contains the error handling elements for SB_SFU. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_ERROR_H +#define SFU_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * This enum must start from 0. + * When adding a new error in the enum below please also: + * 1. update IS_SFU_EXCPT + * 2. update m_aErrorStrings + */ +typedef enum +{ + SFU_EXCPT_NONE = 0UL, + /* System errors */ + SFU_EXCPT_MEMORY_FAULT, + SFU_EXCPT_HARD_FAULT, + SFU_EXCPT_TAMPERING_FAULT, + /* Specific errors */ + SFU_EXCPT_LOCK_SE_SERVICES_ERR, +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + SFU_EXCPT_FW_TOO_BIG, /* The binary is too big to be installed */ + SFU_EXCPT_COM_ERR, /* COM error during the local download of the binary */ +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + SFU_EXCPT_HEADER_AUTH_ERR, /* header authentication failure */ + SFU_EXCPT_DECRYPT_ERR, /* Decrypt failure */ + SFU_EXCPT_SIGNATURE_ERR, /* Signature check failure */ + SFU_EXCPT_FLASH_ERR, /* Problem with FLASH */ + SFU_EXCPT_FLASH_CFG_ERR, /* Flash configuration issue (external flash) */ + SFU_EXCPT_HEADER_ERASING_ERR, /* Header erasing failure */ + SFU_EXCPT_HEADER_VALIDATION_ERR, /* Header validation failure */ + SFU_EXCPT_ADDITIONAL_CODE_ERR, /* Additional code detected beyond the firmware image (malicious SW) */ + SFU_EXCPT_FWIMG_SWAP_ERR, /* Problem while swapping the images */ + SFU_EXCPT_FWIMG_ROLLBACK_ERR, /* Problem during rollback process */ + SFU_EXCPT_FWIMG_ROLLBACK_PREV_ID_ERR,/* Backed-up firmware not identified */ + SFU_EXCPT_BACKUP_COPY_FAILURE_ERR, /* Copy in the backup slot failure */ + SFU_EXCPT_DWL_SLOT_ERASING_ERR, /* Dwl slot erasing failure */ + SFU_EXCPT_TRAILER_ERASING_ERR, /* Trailer update failure */ + SFU_EXCPT_TRAILER_UPDATE_ERR, /* Trailer update failure */ + SFU_EXCPT_FWIMG_MAGIC_ERR, /* Problem with a FWIMG pattern */ + SFU_EXCPT_VERSION_ERR, /* Anti-rollback check rejected the version to be installed */ + /* Unknown error */ + SFU_EXCPT_UNKNOWN /* To be kept as last error */ +} SFU_EXCPT_IdTypeDef; /*!< Errors, Exception, Faults Id */ + +/* External variables --------------------------------------------------------*/ + +/* Exported macros -----------------------------------------------------------*/ + +/* Exported functions ------------------------------------------------------- */ +void SFU_EXCPT_SetError(SFU_EXCPT_IdTypeDef eExceptionId); +void SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); +void SFU_EXCPT_Security_Error(void); + +SFU_ErrorStatus SFU_EXCPT_Init(void); +SFU_ErrorStatus SFU_EXCPT_DeInit(void); + +void SFU_EXCPT_ResetExceptionHandler(SFU_EXCPT_IdTypeDef eExceptionId); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_ERROR_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fsm_states.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fsm_states.h new file mode 100644 index 00000000..5eed78d5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fsm_states.h @@ -0,0 +1,115 @@ +/** + ****************************************************************************** + * @file sfu_fsm_states.h + * @author MCD Application Team + * @brief This file defines the SB_SFU Finite State Machine states. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_FSM_STATES_H +#define SFU_FSM_STATES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "app_sfu.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * FSM states: this enum must start from 0. + */ +typedef enum +{ + SFU_STATE_CHECK_STATUS_ON_RESET = 0U, /*!< checks the reset cause and decide how to proceed */ +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) + SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD, /*!< SFU checks if a local download must be handled */ + SFU_STATE_DOWNLOAD_NEW_USER_FW, /*!< downloads the encrypted firmware to be installed */ +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) || (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ +#ifdef KMS_ENABLED + SFU_STATE_CHECK_KMS_BLOB_TO_INSTALL, /*!< SFU checks if a kms blob download must be handled */ + SFU_STATE_INSTALL_KMS_BLOB, /* !< download the new kms_blob */ +#endif /* KMS_ENABLED */ + SFU_STATE_VERIFY_USER_FW_STATUS, /*!< checks the internal FLASH state to derive a status */ + SFU_STATE_INSTALL_NEW_USER_FW, /*!< decrypts and installs the firmware stored in dwl slot*/ + SFU_STATE_VERIFY_USER_FW_SIGNATURE, /*!< checks the validity of the active firmware */ + SFU_STATE_EXECUTE_USER_FW, /*!< launch the user application */ + SFU_STATE_RESUME_INSTALL_NEW_USER_FW, /*!< resume interrupted installation of firmware */ + SFU_STATE_ROLLBACK_PREV_USER_FW, /*!< rollback with previous firmware */ + SFU_STATE_HANDLE_CRITICAL_FAILURE, /*!< deal with the critical failures */ + SFU_STATE_REBOOT_STATE_MACHINE /*!< a reboot is forced */ +} SFU_BOOT_StateMachineTypeDef; /*!< SFU BOOT State Machine States */ + +/* External variables --------------------------------------------------------*/ +/** + * The following strings associated to the SM state are used for debugging purpose. + * WARNING: The string array must match perfectly with the SFU_BOOT_StateMachineTypeDef defined above. + * And the above enum must be a sequence starting from 0 + */ +#ifdef SFU_DEBUG_MODE +#if defined(SFU_VERBOSE_DEBUG_MODE) && defined (SFU_BOOT_C) +char *m_aStateMachineStrings[] = { "Checking Status on Reset.", +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + "Checking if new Fw Image available to download.", + "Downloading new Fw Image.", +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + "Verifying Fw Image status.", + "Installing new Fw Image.", + "Verifying Fw Image signature.", + "Executing Fw Image.", + "Resuming installation of new Fw Image.", + "Rollback with previous Fw Image.", + "Handling a critical failure.", + "Rebooting the State Machine" + }; +#endif /* SFU_VERBOSE_DEBUG_MODE && SFU_BOOT_C */ + +#endif /* SFU_DEBUG_MODE */ + +/* Exported macros -----------------------------------------------------------*/ +/************ SFU SM States****************************************************/ +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) +#define IS_SFU_SM_STATE(STATE) (((STATE) == (uint8_t)SFU_STATE_CHECK_STATUS_ON_RESET) || \ + ((STATE) == (uint8_t)SFU_STATE_CHECK_NEW_FW_TO_DOWNLOAD) || \ + ((STATE) == (uint8_t)SFU_STATE_DOWNLOAD_NEW_USER_FW) || \ + ((STATE) == (uint8_t)SFU_STATE_INSTALL_NEW_USER_FW) || \ + ((STATE) == (uint8_t)SFU_STATE_VERIFY_USER_FW_STATUS) || \ + ((STATE) == (uint8_t)SFU_STATE_VERIFY_USER_FW_SIGNATURE) || \ + ((STATE) == (uint8_t)SFU_STATE_EXECUTE_USER_FW) || \ + ((STATE) == (uint8_t)SFU_STATE_RESUME_INSTALL_NEW_USER_FW)|| \ + ((STATE) == (uint8_t)SFU_STATE_ROLLBACK_PREV_USER_FW)|| \ + ((STATE) == (uint8_t)SFU_STATE_HANDLE_CRITICAL_FAILURE) || \ + ((STATE) == (uint8_t)SFU_STATE_REBOOT_STATE_MACHINE)) /*!< SFU SM States*/ +#else +#define IS_SFU_SM_STATE(STATE) (((STATE) == (uint8_t)SFU_STATE_CHECK_STATUS_ON_RESET) || \ + ((STATE) == (uint8_t)SFU_STATE_INSTALL_NEW_USER_FW) || \ + ((STATE) == (uint8_t)SFU_STATE_VERIFY_USER_FW_STATUS) || \ + ((STATE) == (uint8_t)SFU_STATE_VERIFY_USER_FW_SIGNATURE) || \ + ((STATE) == (uint8_t)SFU_STATE_EXECUTE_USER_FW) || \ + ((STATE) == (uint8_t)SFU_STATE_RESUME_INSTALL_NEW_USER_FW)|| \ + ((STATE) == (uint8_t)SFU_STATE_ROLLBACK_PREV_USER_FW)|| \ + ((STATE) == (uint8_t)SFU_STATE_HANDLE_CRITICAL_FAILURE) || \ + ((STATE) == (uint8_t)SFU_STATE_REBOOT_STATE_MACHINE)) /*!< SFU SM States*/ +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_FSM_STATES_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_common.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_common.c new file mode 100644 index 00000000..a8fd85f8 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_common.c @@ -0,0 +1,1137 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_common.c + * @author MCD Application Team + * @brief This file provides set of firmware functions to manage the Firmware Images. + * This file contains the "common" functionalities of the image handling. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_FWIMG_COMMON_C + +/* Includes ------------------------------------------------------------------*/ +#include +#include "main.h" +#include "sfu_fsm_states.h" /* needed for sfu_error.h */ +#include "sfu_error.h" +#include "sfu_low_level.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "se_interface_bootloader.h" +#include "sfu_interface_crypto_scheme.h" +#include "sfu_fwimg_regions.h" +#include "sfu_fwimg_services.h" +#include "sfu_fwimg_internal.h" +#include "sfu_trace.h" +#include "sfu_boot.h" + + + +/* Private variables ---------------------------------------------------------*/ +static uint8_t fw_tag_validated[SFU_NB_MAX_ACTIVE_IMAGE][SE_TAG_LEN]; + +/* Global variables ----------------------------------------------------------*/ +/** + * FWIMG status variables used to log errors and display debug messages. + * This is related to FLASH operations. + * This is handled with STATUS_FWIMG. + */ +SFU_IMG_StatusTypeDef SFU_IMG_Status; +uint32_t SFU_IMG_Line; + +/** + * FW header (metadata) of the active FW in active slot: structured format (access by fields) + */ +SE_FwRawHeaderTypeDef fw_image_header_validated; + +/** + * FW header (metadata) of the candidate FW in dwl slot: structured format (access by fields) + */ +SE_FwRawHeaderTypeDef fw_image_header_to_test; + +/* Functions Definition : helper ---------------------------------------------*/ +/** + * @brief Memory compare with constant time execution. + * @note Objective is to avoid basic attacks based on time execution + * @param pAdd1 Address of the first buffer to compare + * @param pAdd2 Address of the second buffer to compare + * @param Size Size of the comparison + * @retval SFU_ SUCCESS if equal, a SFU_error otherwise. + */ +SFU_ErrorStatus MemoryCompare(uint8_t *pAdd1, uint8_t *pAdd2, uint32_t Size) +{ + uint8_t result = 0x00U; + uint32_t i; + + for (i = 0U; i < Size; i++) + { + result |= pAdd1[i] ^ pAdd2[i]; + } + + if (result == 0x00U) + { + return SFU_SUCCESS; + } + else + { + return SFU_ERROR; + } +} + + +/** + * @brief Check header signature + * @param pFwImageHeader: pointer to raw header. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus VerifyHeaderSignature(SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef se_status; + uint8_t result = 0x00U; + uint32_t i; + + /* Check if the FW header is authentic : SFU1 / SFU2 / SFU3 */ + if (SFU_IMG_GetFwImageSlot(pFwImageHeader) != SLOT_INACTIVE) + { + /* Unused bytes should be set at 0x00 value + Comparison with constant time execution */ + for (i = 0U; i < sizeof(pFwImageHeader->Reserved); i++) + { + result |= pFwImageHeader->Reserved[i] ^ 0x00U; + } + + if (result == 0x00U) + { + /* Check signature of the FW header */ + if (SE_VerifyHeaderSignature(&se_status, pFwImageHeader) == SE_SUCCESS) + { + FLOW_STEP(uFlowCryptoValue, FLOW_STEP_AUTHENTICATE); + e_ret_status = SFU_SUCCESS; + } + } + } + + return e_ret_status; +} + + +/** + * @brief Secure Engine Firmware signature verification (FW in non contiguous area). + * It handles Firmware TAG verification of a complete buffer by calling + * SE_AuthenticateFW_Init, SE_AuthenticateFW_Append and SE_AuthenticateFW_Finish inside the firewall. + * @note: AES_GCM tag: In order to verify the TAG of a buffer, the function will re-encrypt it + * and at the end compare the obtained TAG with the one provided as input + * in pSE_GMCInit parameter. + * @note: SHA-256 tag: a hash of the firmware is performed and compared with the digest stored in the Firmware header. + * @param pSE_Status: Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param SlotNumber index of the slot in the list + * @param pSE_Metadata: Firmware metadata. + * @param pSE_Payload: pointer to Payload Buffer descriptor. + * @param SE_FwType: Type of Fw Image. + * This parameter can be SE_FW_IMAGE_COMPLETE or SE_FW_IMAGE_PARTIAL. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SFU_ErrorStatus VerifyFwSignatureScatter(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, + SE_FwRawHeaderTypeDef *pSE_Metadata, + SE_Ex_PayloadDescTypeDef *pSE_Payload, uint32_t SE_FwType) +{ + SE_ErrorStatus se_ret_status = SE_ERROR; + SFU_ErrorStatus sfu_ret_status = SFU_SUCCESS; + /* Loop variables */ + uint32_t i; + uint32_t j; + /* Variables to handle the FW image chunks to be injected in the verification procedure and the result */ + uint32_t fw_tag_len; /* length of the authentication tag to be verified */ + uint32_t fw_verified_total_size = 0; /* number of bytes that have been processed during authentication check */ + uint32_t fw_chunk_size; /* size of a FW chunk to be verified */ + /* Authentication tag computed in this procedure (to be compared with the one stored in the FW metadata) */ + uint8_t fw_tag_output[SE_TAG_LEN] __attribute__((aligned(8))); + /* FW chunk produced by the verification procedure if any */ + uint8_t fw_chunk[CHUNK_SIZE_SIGN_VERIFICATION] __attribute__((aligned(8))); + /* FW chunk provided as input to the verification procedure */ + uint8_t fw_image_chunk[CHUNK_SIZE_SIGN_VERIFICATION] __attribute__((aligned(8))); + /* Variables to handle the FW image (this will be split in chunks) */ + uint32_t payloadsize; + uint32_t ppayload; + uint32_t scatter_nb; + /* Variables to handle FW image size and tag */ + uint32_t fw_size; + uint8_t *fw_tag; + + /* Check the pointers allocation */ + if ((pSeStatus == NULL) || (pSE_Metadata == NULL) || (pSE_Payload == NULL)) + { + return SFU_ERROR; + } + if ((pSE_Payload->pPayload[0] == 0U) || ((pSE_Payload->pPayload[1] == 0U) && (pSE_Payload->PayloadSize[1] != 0U))) + { + return SFU_ERROR; + } + + /* Check the parameters value and set fw_size and fw_tag to check */ + if (SE_FwType == SE_FW_IMAGE_COMPLETE) + { + fw_size = pSE_Metadata->FwSize; + fw_tag = pSE_Metadata->FwTag; + } + else if (SE_FwType == SE_FW_IMAGE_PARTIAL) + { + fw_size = pSE_Metadata->PartialFwSize; + fw_tag = pSE_Metadata->PartialFwTag; + } + else + { + return SFU_ERROR; + } + + if ((pSE_Payload->PayloadSize[0] + pSE_Payload->PayloadSize[1]) != fw_size) + { + return SFU_ERROR; + } + + /* fix number of scatter block */ + if (pSE_Payload->PayloadSize[1] != 0U) + { + scatter_nb = 2U; + } + else + { + scatter_nb = 1U; + } + + + /* Encryption process*/ + se_ret_status = SE_AuthenticateFW_Init(pSeStatus, pSE_Metadata, SE_FwType); + + /* check for initialization errors */ + if ((se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) + { + for (j = 0; j < scatter_nb; j++) + { + payloadsize = pSE_Payload->PayloadSize[j]; + ppayload = pSE_Payload->pPayload[j]; + i = 0; + fw_chunk_size = CHUNK_SIZE_SIGN_VERIFICATION; + + while ((i < (payloadsize / CHUNK_SIZE_SIGN_VERIFICATION)) && (*pSeStatus == SE_OK) && + (sfu_ret_status == SFU_SUCCESS)) + { + + sfu_ret_status = SFU_LL_FLASH_Read(fw_image_chunk, (uint8_t *)ppayload, fw_chunk_size) ; + if (sfu_ret_status == SFU_SUCCESS) + { + se_ret_status = SE_AuthenticateFW_Append(pSeStatus, fw_image_chunk, (int32_t)fw_chunk_size, + fw_chunk, (int32_t *)&fw_chunk_size); + } + else + { + *pSeStatus = SE_ERR_FLASH_READ; + se_ret_status = SE_ERROR; + sfu_ret_status = SFU_ERROR; + } + ppayload += fw_chunk_size; + fw_verified_total_size += fw_chunk_size; + i++; + } + /* this the last path , size can be smaller */ + fw_chunk_size = pSE_Payload->pPayload[j] + pSE_Payload->PayloadSize[j] - ppayload; + if ((fw_chunk_size != 0U) && (se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) + { + sfu_ret_status = SFU_LL_FLASH_Read(fw_image_chunk, (uint8_t *)ppayload, fw_chunk_size) ; + if (sfu_ret_status == SFU_SUCCESS) + { + + se_ret_status = SE_AuthenticateFW_Append(pSeStatus, fw_image_chunk, + (int32_t)(payloadsize - (i * CHUNK_SIZE_SIGN_VERIFICATION)), + fw_chunk, (int32_t *)&fw_chunk_size); + } + else + { + *pSeStatus = SE_ERR_FLASH_READ; + se_ret_status = SE_ERROR; + sfu_ret_status = SFU_ERROR; + } + fw_verified_total_size += fw_chunk_size; + } + } + } + + if ((sfu_ret_status == SFU_SUCCESS) && (se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK)) + { + if (fw_verified_total_size <= fw_size) + { + /* Do the Finalization, check the authentication TAG*/ + fw_tag_len = sizeof(fw_tag_output); + se_ret_status = SE_AuthenticateFW_Finish(pSeStatus, fw_tag_output, (int32_t *)&fw_tag_len); + + if ((se_ret_status == SE_SUCCESS) && (*pSeStatus == SE_OK) && (fw_tag_len == SE_TAG_LEN)) + { + /* Firmware tag verification */ + if (MemoryCompare(fw_tag_output, fw_tag, SE_TAG_LEN) != SFU_SUCCESS) + { + *pSeStatus = SE_SIGNATURE_ERR; + se_ret_status = SE_ERROR; + sfu_ret_status = SFU_ERROR; + + /* Save result for active slot : + to avoid single fault attack the signature will be double checked before UserApp execution */ + if ((SlotNumber >= SLOT_ACTIVE_1) && (SlotNumber < SLOT_DWL_1)) + { + (void) memset(&fw_tag_validated[SlotNumber - SLOT_ACTIVE_1][0U], 0x00, SE_TAG_LEN); + } + } + else + { + FLOW_STEP(uFlowCryptoValue, FLOW_STEP_INTEGRITY); + + /* Save result for active slot : + to avoid single fault attacje the signature will be doble checked before UserApp execution */ + if ((SlotNumber >= SLOT_ACTIVE_1) && (SlotNumber < SLOT_DWL_1)) + { + (void) memcpy(&fw_tag_validated[SlotNumber - SLOT_ACTIVE_1][0U], fw_tag_output, SE_TAG_LEN); + } + } + } + else + { + sfu_ret_status = SFU_ERROR; + } + } + else + { + sfu_ret_status = SFU_ERROR; + } + } + else + { + sfu_ret_status = SFU_ERROR; + } + return sfu_ret_status; +} + +/** + * @brief Fill authenticated info in SE_FwImage. + * @param SFU_APP_Status + * @param pBuffer + * @param BufferSize + * @retval SFU_SUCCESS if successful, a SFU_ERROR otherwise. + */ +SFU_ErrorStatus ParseFWInfo(SE_FwRawHeaderTypeDef *pFwHeader, uint8_t *pBuffer) +{ + /* Check the pointers allocation */ + if ((pFwHeader == NULL) || (pBuffer == NULL)) + { + return SFU_ERROR; + } + (void) memcpy(pFwHeader, pBuffer, sizeof(*pFwHeader)); + return SFU_SUCCESS; +} + +/** + * @brief Verify Image Header in the slot given as a parameter + * @param SlotNumber index of the slot in the list + * @param pFwImageHeader pointer to a structure to handle the header info (filled by this function) + * @note Not used in Alpha version - + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus CheckAndGetFWHeader(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* use api read to detect possible ECC error */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) pFwImageHeader, (uint8_t *) SlotHeaderAdd[SlotNumber], + sizeof(SE_FwRawHeaderTypeDef)); + if (e_ret_status == SFU_SUCCESS) + { + /* Verify signature */ + e_ret_status = VerifyHeaderSignature(pFwImageHeader); + } + return e_ret_status; +} + +/** + * @brief Verify Fw signature of binary contiguous in flash + * @param pSeStatus pointer giving the SE status result + * @param SlotNumber flash slot to check + * @param pFwImageHeader pointer to fw header + * @param SlotNumber flash slot to check + * @param SE_FwType: Type of Fw Image. + * This parameter can be SE_FW_IMAGE_COMPLETE or SE_FW_IMAGE_PARTIAL. + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus VerifyFwSignature(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, + SE_FwRawHeaderTypeDef *pFwImageHeader, + uint32_t SE_FwType) +{ + SE_Ex_PayloadDescTypeDef pse_payload; + uint32_t fw_size; + uint32_t fw_offset; + + /* put it OK, to discriminate error in SFU FWIMG parts */ + *pSeStatus = SE_OK; + + /* Check the parameters value */ + if (pFwImageHeader == NULL) + { + return SFU_ERROR; + } + if ((SE_FwType != SE_FW_IMAGE_PARTIAL) && (SE_FwType != SE_FW_IMAGE_COMPLETE)) + { + return SFU_ERROR; + } + + /* Check SE_FwType parameter, and fix size and offset accordingly */ + switch (SE_FwType) + { + case SE_FW_IMAGE_COMPLETE : + fw_size = pFwImageHeader->FwSize; + fw_offset = 0U; + break; + case SE_FW_IMAGE_PARTIAL : + fw_size = pFwImageHeader->PartialFwSize; +#if !defined(SFU_NO_SWAP) + fw_offset = pFwImageHeader->PartialFwOffset % SLOT_SIZE(SLOT_SWAP); +#else + fw_offset = pFwImageHeader->PartialFwOffset; +#endif /* !SFU_NO_SWAP */ + break; + default : + /* error */ + fw_size = 0U; + fw_offset = 0U; + break; + } + + pse_payload.pPayload[0] = SlotStartAdd[SlotNumber] + fw_offset + SFU_IMG_IMAGE_OFFSET; + pse_payload.PayloadSize[0] = fw_size; + pse_payload.pPayload[1] = 0U; + pse_payload.PayloadSize[1] = 0U; + + return VerifyFwSignatureScatter(pSeStatus, SlotNumber, pFwImageHeader, &pse_payload, SE_FwType); +} + +/** + * @brief Verifies the validity of a slot. + * @note Control if there is no additional code beyond the firmware image (malicious SW). + * @param pSlotBegin Start address of a slot. + * @param uSlotSize Size of a slot. + * @param uFwSize Size of the firmware image. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus VerifySlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uFwSize) +{ + uint8_t *pdata; + uint32_t length; + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check is already clean */ + pdata = pSlotBegin + SFU_IMG_IMAGE_OFFSET + uFwSize; + length = uSlotSize - SFU_IMG_IMAGE_OFFSET - uFwSize; + e_ret_status = SFU_LL_FLASH_Compare(pdata, 0x00000000U, 0xFFFFFFFFU, length); + + return e_ret_status; +} + +/** + * @brief This function clean-up the flash + * @note Not designed to clean-up area inside secure engine isolation. + * @note To clean the slot without erasing the header we write "0x00" except if already written + * @param pSlotBegin Start address of a slot. + * @param uSlotSize Size of a slot. + * @param uOffset Offset in the slot to start cleanup, until end of the slot. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus CleanUpSlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uOffset) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t pdata; + uint32_t slot_begin; + SFU_LL_FLASH_write_t pattern; + SFU_LL_FLASH_write_t value; + SFU_FLASH_StatusTypeDef flash_if_info; + + /* Clean-up pattern initialization */ + (void) memset((void *)&pattern, 0x00, sizeof(SFU_LL_FLASH_write_t)); + + /* Cleaning operation */ + slot_begin = (uint32_t) pSlotBegin; + for (pdata = slot_begin + uOffset; pdata < (slot_begin + uSlotSize); pdata += sizeof(SFU_LL_FLASH_write_t)) + { + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &value, (uint8_t *) pdata, sizeof(SFU_LL_FLASH_write_t)); + + if (e_ret_status == SFU_SUCCESS) + { + /* If read succeed, then the pattern write is performed only if pattern is not already present */ + if (memcmp((void *) &value, (void *) &pattern, sizeof(SFU_LL_FLASH_write_t)) != 0) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, (uint8_t *) pdata, (uint8_t *) &pattern, + sizeof(SFU_LL_FLASH_write_t)); + } + } + else + { + /* If read fail, then the write is performed unconditionally */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, (uint8_t *) pdata, (uint8_t *) &pattern, + sizeof(SFU_LL_FLASH_write_t)); + } + + /* Reload Watchdog every 4Kbytes */ + if ((pdata % 0x1000U) == 0U) + { + (void) SFU_LL_SECU_IWDG_Refresh(); + } + } + return e_ret_status; +} + +/* Functions Definition : services ------------------------------------------- */ + +/** + * @brief FW Image Handling (FWIMG) initialization function. + * Checks the validity of the settings related to image handling (slots size and alignments...). + * @note The system initialization must have been performed before calling this function (flash driver ready to be + * used...etc...). + * Must be called first (and once) before calling the other Image handling services. + * @param None. + * @retval SFU_IMG_InitStatusTypeDef SFU_IMG_INIT_OK if successful, an error code otherwise. + */ +SFU_IMG_InitStatusTypeDef SFU_IMG_InitImageHandling(void) +{ + uint32_t i; + SFU_IMG_InitStatusTypeDef e_ret_status = SFU_IMG_INIT_OK; +#if !defined(SFU_NO_SWAP) + SFU_IMG_InitStatusTypeDef e_swap_ret_status; +#endif /*(GENERATOR_2_FW_IMAGE) && !(SFU_NO_SWAP) */ + + /* + * When there is no valid FW in active, the fw_image_header_validated structure is filled with 0s. + * When installing a first FW (after local download) this means that WRITE_TRAILER_MAGIC will write a SWAP magic + * starting with 0s. + * This causes an issue when calling CLEAN_TRAILER_MAGIC (because of this we added an erase that generated + * side-effects). + * To avoid all these problems we can initialize fw_image_header_validated with a non-0 value. + */ + (void) memset((uint8_t *) &fw_image_header_validated, 0xFE, sizeof(fw_image_header_validated)); + + /* + * Sanity check: let's make sure all actives slots are properly aligned with regards to flash constraints + */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { +#if defined(__GNUC__) + __IO uint32_t start_add; + start_add = SlotStartAdd[SLOT_ACTIVE_1 + i]; + if (start_add != 0U) +#else + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) +#endif /* (__GNUC__) */ + { + if (!IS_ALIGNED(SlotStartAdd[SLOT_ACTIVE_1 + i])) + { + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] SLOT_ACTIVE_%d (%x) is not properly aligned\r\n", + i + 1U, SlotStartAdd[SLOT_ACTIVE_1 + i]); + } /* else active slot is properly aligned */ + } + } + + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { +#if defined(__GNUC__) + __IO uint32_t start_add; + start_add = SlotStartAdd[SLOT_DWL_1 + i]; + if (start_add != 0U) +#else + if (SlotStartAdd[SLOT_DWL_1 + i] != 0U) +#endif /* (__GNUC__) */ + { + if (!IS_ALIGNED(SlotStartAdd[SLOT_DWL_1 + i])) + { + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] SLOT_DWL_%d (%x) is not properly aligned\r\n", + i + 1U, SlotStartAdd[SLOT_DWL_1 + 1U]); + } /* else dwl slot is properly aligned */ + } + } + + + /* + * Sanity check: let's make sure the MAGIC patterns used by the internal algorithms match the FLASH constraints. + */ + if (0U != (uint32_t)(MAGIC_LENGTH % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] magic size (%d) is not matching the FLASH constraints\r\n", MAGIC_LENGTH); + } /* else the MAGIC patterns size is fine with regards to FLASH constraints */ + + /* + * Sanity check: let's make sure the Firmware Header Length is fine with regards to FLASH constraints + */ + if (0U != (uint32_t)(SE_FW_HEADER_TOT_LEN % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + /* The code writing the FW header in FLASH requires the FW Header length to match the FLASH constraints */ + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] FW Header size (%d) is not matching the FLASH constraints\r\n", SE_FW_HEADER_TOT_LEN); + } /* else the FW Header Length is fine with regards to FLASH constraints */ + + /* + * Sanity check: let's make sure the chunks used for decrypt match the FLASH constraints + */ + if (0U != (uint32_t)(SFU_IMG_CHUNK_SIZE % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + /* The size of the chunks used to store the decrypted data must be a multiple of the FLASH write length */ + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] Decrypt chunk size (%d) is not matching the FLASH constraints\r\n", SFU_IMG_CHUNK_SIZE); + } /* else the decrypt chunk size is fine with regards to FLASH constraints */ + + /* + * Sanity check: let's make sure the chunk size used for decrypt is fine with regards to AES CBC constraints. + * This block alignment constraint does not exist for AES GCM but we do not want to specialize the code + * for a specific crypto scheme. + */ + if (0U != (uint32_t)((uint32_t)SFU_IMG_CHUNK_SIZE % (uint32_t)AES_BLOCK_SIZE)) + { + /* For AES CBC block encryption/decryption the chunks must be aligned on the AES block size */ + e_ret_status = SFU_IMG_INIT_CRYPTO_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] Chunk size (%d) is not matching the AES CBC constraints\r\n", SFU_IMG_CHUNK_SIZE); + } + + /* + * Sanity check: let's make sure the active slot headers do not overlap SB code area protected by WRP + */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { +#if defined(__GNUC__) + __IO uint32_t start_add; + start_add = SlotStartAdd[SLOT_ACTIVE_1 + i]; + if (start_add != 0U) +#else + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) +#endif /* (__GNUC__) */ + { + if (((SlotStartAdd[SLOT_ACTIVE_1 + i] - FLASH_BASE) / FLASH_PAGE_SIZE) <= SFU_PROTECT_WRP_PAGE_END_1) + { + TRACE("\r\n= [FWIMG] SLOT_ACTIVE_%d overlaps SBSFU code area protected by WRP\r\n", i + 1U); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + } + } + + /* + * Sanity check: let's make sure the dwl slot does not overlap SB code area protected by WRP + */ + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { +#if defined(__GNUC__) + __IO uint32_t start_add; + start_add = SlotStartAdd[SLOT_DWL_1 + i]; + if (start_add != 0U) +#else /* (__GNUC__) */ + if (SlotStartAdd[SLOT_DWL_1 + i] != 0U) +#endif /* (__GNUC__) */ + { + if (((SlotStartAdd[SLOT_DWL_1 + i] - FLASH_BASE) / FLASH_PAGE_SIZE) <= SFU_PROTECT_WRP_PAGE_END_1) + { + TRACE("\r\n= [FWIMG] SLOT_DWL_%d overlaps SBSFU code area protected by WRP\r\n", i + 1U); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + } + } + + + + + /* + * Sanity check: let's make sure the KMS NVM area does not overlap SB code area + */ + if (!(((SB_REGION_ROM_START) > KMS_DATASTORAGE_END) + || ((SB_REGION_ROM_END) < (KMS_DATASTORAGE_START)))) + { + TRACE("\r\n= [FWIMG] KMS NVM area overlaps SB Code area\r\n"); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + + /* + * Sanity check: let's make sure the KMS NVM area does not overlap active slots area + */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + if (!(((SlotStartAdd[SLOT_ACTIVE_1 + i]) > KMS_DATASTORAGE_END) + || ((SlotEndAdd[SLOT_ACTIVE_1 + i]) < (KMS_DATASTORAGE_START)))) + { + TRACE("\r\n= [FWIMG] KMS NVM area overlaps SLOT_ACTIVE_%d area\r\n", i + 1U); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + } + } + + /* + * Sanity check: let's make sure the KMS NVM area does not overlap dwl slot area + */ + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { + if (SlotStartAdd[SLOT_DWL_1 + i] != 0U) + { + if (!(((SlotStartAdd[SLOT_DWL_1 + i]) > KMS_DATASTORAGE_END) + || ((SlotEndAdd[SLOT_DWL_1 + i]) < (KMS_DATASTORAGE_START)))) + { + TRACE("\r\n= [FWIMG] KMS NVM area overlaps SLOT_DWL_%d area\r\n", i + 1U); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + } + } + +#if !defined(SFU_NO_SWAP) + /* + * Sanity check: specific swap process checks + */ + e_swap_ret_status = SFU_IMG_CheckSwapImageHandling(); + if (e_swap_ret_status != SFU_IMG_INIT_OK) + { + e_ret_status = e_swap_ret_status; + } +#endif /* defined(SFU_NO_SWAP) */ + + + return e_ret_status; +} + +/** + * @brief This function makes sure the current active firmware will not be considered as valid any more. + * This function alters the FLASH content. + * @note It is up to the caller to make sure the conditions to call this primitive are met (no check performed before + * running the procedure). + * @param SlotNumber index of the slot in the list + * @retval SFU_SUCCESS if successful,SFU_ERROR error otherwise. + */ +SFU_ErrorStatus SFU_IMG_InvalidateCurrentFirmware(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Reload Watchdog */ + (void) SFU_LL_SECU_IWDG_Refresh(); + + /* erase active slot except Header (under SECoreBin protection) for the anti-rollback check during next Fw update */ + e_ret_status = CleanUpSlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), SFU_IMG_IMAGE_OFFSET); + + return (e_ret_status); +} + +/** + * @brief Verifies the validity of the active firmware image metadata. + * @note This function relies on cryptographic procedures and it is up to the caller to make sure the required + * elements have been configured. + * @note This function populates the FWIMG module variable: fw_image_header_validated + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyActiveImgMetadata(uint32_t SlotNumber) +{ + /* + * If the metadata is valid then 'fw_image_header_validated' is filled with the metadata. + */ + return (CheckAndGetFWHeader(SlotNumber, &fw_image_header_validated)); +} + +/** + * @brief Verifies the validity of the active firmware image. + * @note This function relies on cryptographic procedures and it is up to the caller to make sure the required + * elements have been configured. + * Typically, SFU_IMG_VerifyActiveImgMetadata() must have been called first to populate + * fw_image_header_validated. + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyActiveImg(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status = SE_KO; + + /* + * fw_image_header_validated MUST have been populated with valid metadata first, + */ + e_ret_status = VerifyFwSignature(&e_se_status, SlotNumber, &fw_image_header_validated, SE_FW_IMAGE_COMPLETE); +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (SFU_ERROR == e_ret_status) + { + /* We do not memorize any specific error, the FSM state is already providing the info */ + TRACE("\r\n= SFU_IMG_VerifyActiveImg failure with se_status=%d!", e_se_status); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + return (e_ret_status); +} + +/** + * @brief Verifies if no malicious code beyond Fw Image in an active slot. + * @note SFU_IMG_VerifyActiveImgMetadata() must have been called first to populate fw_image_header_validated. + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyActiveSlot(uint32_t SlotNumber) +{ + /* + * fw_image_header_validated MUST have been populated with valid metadata first, + */ + return (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), fw_image_header_validated.FwSize)); +} + +/** + * @brief Verifies if no malicious code in active slot. + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_VerifyEmptyActiveSlot(uint32_t SlotNumber) +{ + return (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SLOT_SIZE(SlotNumber), 0U)); +} + +/** + * @brief Control firmware signature + * @note This control will be done twice for security reasons (first control done in VerifyFwSignatureScatter) + * @param SlotNumber index of the slot in the list + * @retval SFU_SUCCESS if successful,SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_ControlActiveImgTag(uint32_t SlotNumber) +{ + /* + * fw_image_header_validated MUST have been populated with valid metadata first, + */ + if (MemoryCompare(fw_tag_validated[SlotNumber - SLOT_ACTIVE_1], fw_image_header_validated.FwTag, + SE_TAG_LEN) != SFU_SUCCESS) + { + return SFU_ERROR; + } + else + { + FLOW_STEP(uFlowCryptoValue, FLOW_STEP_INTEGRITY); + return SFU_SUCCESS; + } + +} + +/** + * @brief Launches the user application. + * The caller must be prepared to never get the hand back after calling this function. + * If a problem occurs, it must be memorized in the bootinfo area. + * If the caller gets the hand back then this situation must be handled as a critical error. + * @note It is up to the caller to make sure the conditions to call this primitive are met + * (typically: no security check performed before launching the firmware). + * @note This function only handles the "system" aspects. + * It is up to the caller to manage any security related action (enable ITs, disengage MPU, clean RAM...). + * Nevertheless, cleaning-up the stack and heap used by SB_SFU is part of the system actions handled by this + * function (as this needs to be done just before jumping into the user application). + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus Does not return if successful, returns SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_LaunchActiveImg(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + + /* Verify if authentication/integrity/lock SE service performed */ + FLOW_CONTROL_CHECK(uFlowCryptoValue, FLOW_CTRL_LOCK_SERVICE); + + uint32_t jump_address ; + typedef void (*Function_Pointer)(void); + Function_Pointer p_jump_to_function; + +#if defined(SFU_MPU_PROTECT_ENABLE) +#if defined(SFU_MPU_USERAPP_ACTIVATION) + e_ret_status = SFU_LL_SECU_SetProtectionMPU_UserApp(); +#else + HAL_MPU_Disable(); +#endif /* SFU_MPU_USERAPP_ACTIVATION */ +#endif /* SFU_MPU_PROTECT_ENABLE */ + + /* Avoid systick interruption during UserApp start-up + systick will be re-initialized by HAL_Init() during execution of main() from UserApp */ + HAL_SuspendTick(); + + /* Initialize address of user application to jump into */ + jump_address = *(__IO uint32_t *)((SlotStartAdd[SlotNumber] + SFU_IMG_IMAGE_OFFSET + 4)); + p_jump_to_function = (Function_Pointer) jump_address; + + /* Initialize user application's Stack Pointer */ + __set_MSP(*(__IO uint32_t *)(SlotStartAdd[SlotNumber] + SFU_IMG_IMAGE_OFFSET)); + + if (SFU_SUCCESS == e_ret_status) + { + /* JUMP into User App */ + p_jump_to_function(); + } + + /* The point below should NOT be reached */ + return (e_ret_status); +} + +/** + * @brief Get the version of the active FW + * @note It is up to the caller to make sure the active slot contains a valid active FW. + * @note In the current implementation the header is checked (authentication) and no version is returned if this check + * fails. + * @param SlotNumber index of the slot in the list + * @retval the FW version if the header is valid (coded on uint16_t), 0 otherwise + */ +uint16_t SFU_IMG_GetActiveFwVersion(uint32_t SlotNumber) +{ + SE_FwRawHeaderTypeDef fw_image_header; + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint16_t version = 0; + + /* check the header of the active FW */ + e_ret_status = CheckAndGetFWHeader(SlotNumber, &fw_image_header); + if (e_ret_status == SFU_SUCCESS) + { + /* retrieve the version from the header without any further check */ + version = fw_image_header.FwVersion; + } + + return (version); +} + +/** + * @brief Detect if a FW is present in a slot. + * @note Detection done based on MAGIC header + FW signature. Header verification + * not done at this stage for timing optimization. + * @param SlotNumber index of the slot in the list + * @retval SFU_SUCCESS if successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_DetectFW(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t *pbuffer; + uint8_t buffer[SE_FW_HEADER_TOT_LEN]; + SE_FwRawHeaderTypeDef *p_header; + + /* Read header */ + pbuffer = (uint8_t *) SlotHeaderAdd[SlotNumber]; + if (SFU_LL_FLASH_Read(buffer, pbuffer, sizeof(buffer)) == SFU_SUCCESS) + { + /* Check if the FW header is authentic : SFU1 / SFU2 / SFU3 */ + p_header = (SE_FwRawHeaderTypeDef *)(uint32_t)buffer; + if (SFU_IMG_GetFwImageSlot(p_header) != SLOT_INACTIVE) + { + /* + * Control if the first 32 bytes (could be more but time consuming ...) are significants + * At this location we should find the vector table. + * Objective is to detect if the FW image has been erased + * ==> this is the case after SFU_IMG_InvalidateCurrentFirmware() (could be an attack attempt) + */ + if (VerifySlot((uint8_t *) SlotStartAdd[SlotNumber], SFU_IMG_IMAGE_OFFSET + 0x20U, 0U) != SFU_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + } + } + } + return e_ret_status; +} + +/** + * @brief Validate the active FW image in active slot by installing the header + * @param SlotNumber index of the slot in the list + * @param pFwImageHeader pointer in ram to the header to install + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ + +SFU_ErrorStatus SFU_IMG_Validation(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFWImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_status; + + /* Header writing: encrypted part with signature */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *) SlotHeaderAdd[SlotNumber], (uint8_t *) pFWImageHeader, + SE_FW_AUTH_LEN + SE_FW_HEADER_SIGN_LEN); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + + /* Header writing : Do not update image state part */ + + /* Header writing: previous FW image fingerprint */ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *)(SlotHeaderAdd[SlotNumber] + SE_FW_HEADER_TOT_LEN - + SE_FW_HEADER_FINGERPRINT_LEN), + (uint8_t *) pFWImageHeader->PrevHeaderFingerprint, SE_FW_HEADER_FINGERPRINT_LEN); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + } + + + return e_ret_status; +} + +/** + * @brief Get firmware image ID from header. + * @param pFwImageHeader pointer to a structure to handle the header info + * @retval Fw Id : SLOT_ACTIVE_1 / 2 /... / SFU_NB_MAX_ACTIVE_IMAGE + */ +uint32_t SFU_IMG_GetFwImageSlot(SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + uint32_t active_slot; + + if (memcmp(pFwImageHeader->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) + { + active_slot = SLOT_ACTIVE_1; + } +#if (SFU_NB_MAX_ACTIVE_IMAGE > 1) + else if (memcmp(pFwImageHeader->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) + { + active_slot = SLOT_ACTIVE_2; + } +#endif /* (SFU_NB_MAX_ACTIVE_IMAGE > 1) */ +#if (SFU_NB_MAX_ACTIVE_IMAGE > 2) + else if (memcmp(pFwImageHeader->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) + { + active_slot = SLOT_ACTIVE_3; + } +#endif /* (SFU_NB_MAX_ACTIVE_IMAGE > 2) */ + else + { + active_slot = SLOT_INACTIVE; + } + + return active_slot; +} + +/** + * @brief Check candidate image version is allowed. + * @param ActiveSlot Slot identification used in case of secure counters usage + * @param CurrentVersion Version of currently installed image if any + * @param CandidateVersion Version of candidate image + * @retval SFU_SUCCESS if candidate image version is allowed, SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus SFU_IMG_CheckFwVersion(uint32_t ActiveSlot, uint16_t CurrentVersion, uint16_t CandidateVersion) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + UNUSED(ActiveSlot); + + /* If the header of the active firmware is not valid, the CurrentVersion is 0 */ + if (CurrentVersion == 0U) + { + /* + * If the header of the active firmware is not valide (could comes from an attak atempt, we authorize only the + * installation of a specific version identified by SFU_FW_VERSION_INIT_NUM. + */ + if (CandidateVersion == SFU_FW_VERSION_INIT_NUM) + { + /* Candidate version is allowed */ + e_ret_status = SFU_SUCCESS; + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + else + { + TRACE("\r\n\t Init version:%d - Current version:%d - Candidate version:%d : Installation not allowed!", SFU_FW_VERSION_INIT_NUM, CurrentVersion, CandidateVersion); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + else + { + /* + * It is not allowed to install a Firmware with a lower version than the active firmware. + * But we authorize the re-installation of the current firmware version. + * We also check that the candidate version is at least the min. allowed version for this device. + */ + if ((CandidateVersion >= CurrentVersion) && (CandidateVersion >= SFU_FW_VERSION_START_NUM)) + { + /* Candidate version is allowed */ + e_ret_status = SFU_SUCCESS; + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + else + { + TRACE("\r\n\t Init version:%d - Current version:%d - Candidate version:%d : Installation not allowed!", SFU_FW_VERSION_INIT_NUM, CurrentVersion, CandidateVersion); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + } + + return e_ret_status; +} + +/** + * @brief Verifies the validity of the metadata associated to a candidate image. + * The anti-rollback check is performed. + * Errors can be memorized in the bootinfo area but no action is taken in this procedure. + * @note It is up to the caller to make sure the conditions to call this primitive are met (no check performed before + * running the procedure): + * SFU_IMG_CheckPendingInstallation should be called first. + * @note For the local loader (@ref SECBOOT_USE_LOCAL_LOADER), the candidate metadata is verified by: + * @ref SFU_APP_VerifyFwHeader. + * But, SFU_IMG_CheckCandidateVersion will be called when the installation of the new image is triggered. + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, error code otherwise + */ + +/* anti-rollback mechanism is tested twice to avoid basic hardware attack + ==> compiler optimization is disabled for this reason */ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O0"))) +#endif /* __ICCARM__ */ + +SFU_ErrorStatus SFU_IMG_CheckCandidateVersion(uint32_t DwlSlot) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_status; + uint32_t active_slot; + uint16_t cur_ver; + uint16_t verif_ver; + + /* + * - Candidate FW Header Authentication + * An authentication check is already performed with SFU_IMG_CheckPendingInstallation(). + * As a consequence: fw_image_header_to_test is already populated + * + * - Check version is allowed + * SFU_IMG_GetActiveFwVersion() returns 0 if the header of active firmware is not valid + */ + + /* Header analysis to find slot based on number with magic tag */ + active_slot = SFU_IMG_GetFwImageSlot(&fw_image_header_to_test); + + /* Get the version of active_slot */ + cur_ver = SFU_IMG_GetActiveFwVersion(active_slot); + + if (SFU_IMG_CheckFwVersion(active_slot, cur_ver, fw_image_header_to_test.FwVersion) != SFU_SUCCESS) + { + /* The installation is forbidden */ + /* Memorize this error as this will be handled as a critical failure */ + SFU_EXCPT_SetError(SFU_EXCPT_VERSION_ERR); + + /* We would enter an infinite loop of installation attempts if we do not clean-up the dwl slot header */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *)SlotStartAdd[DwlSlot], SFU_IMG_IMAGE_OFFSET); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + /* leave now to handle the critical failure in the appropriate FSM state */ + e_ret_status = SFU_ERROR; + } + else + { + /* the anti-rollback check succeeds: the version is fine */ + /* double check to avoid basic hardware attack attack */ + verif_ver = SFU_IMG_GetActiveFwVersion(active_slot); + e_ret_status = SFU_IMG_CheckFwVersion(active_slot, verif_ver, fw_image_header_to_test.FwVersion); + } + + /* Return the result */ + return (e_ret_status); +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_internal.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_internal.h new file mode 100644 index 00000000..a2e0d18c --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_internal.h @@ -0,0 +1,134 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_internal.h + * @author MCD Application Team + * @brief This file contains internal definitions (private) for SFU_FWIMG functionalities. + * This file should be included only by sfu_fwimg_core.c and sfu_fwimg_services.c. + * Nevertheless, the SFU_KMS module is allowed to include it to re-use the variable + * fw_image_header_to_test to install an KMS blob. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_FWIMG_INTERNAL_H +#define SFU_FWIMG_INTERNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "se_def.h" +#include "sfu_fwimg_regions.h" +#include "kms_blob_metadata.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief Payload Buffer descriptor. + * This structure describes how a Firmware is split in Flash. + * In the nominal case a Firmware is stored in 1 contiguous area. + * But, a Firmware can be split in up to 2 areas (typically when a FW installation procedure is interrupted or after a + * decrypt operation). + */ +typedef struct +{ + uint32_t pPayload[2]; /*!< table containing payload pointer*/ + uint32_t PayloadSize[2]; /*!< table containing Payload Size*/ +} SE_Ex_PayloadDescTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/** + * @brief SFU_IMG Flash Status Type Definition + * Status of a FLASH operation. + */ +typedef enum +{ + SFU_IMG_OK = 0x0U, /*!< No problem reported */ + SFU_IMG_FLASH_ERASE_FAILED, /*!< FLASH erase failure */ + SFU_IMG_FLASH_WRITE_FAILED, /*!< FLASH write failure */ + SFU_IMG_FLASH_READ_FAILED, /*!< FLASH read failure */ +} SFU_IMG_StatusTypeDef; + +/** + * @brief RAM chunk used for decryption / comparison / swap + * it is the size of RAM buffer allocated in stack and used for decrypting/moving images. + * some function allocates 2 buffer of this size in stack. + * As image are encrypted by 128 bits blocks, this value is 16 bytes aligned. + */ +#define CHUNK_SIZE_SIGN_VERIFICATION (1024UL) /*!< Signature verification chunk size*/ + +#define SFU_IMG_CHUNK_SIZE (512UL) +#define AES_BLOCK_SIZE (16UL) /*!< Size of an AES block to check padding needs for decrypting */ + +/* Exported macros -----------------------------------------------------------*/ +/** + * @brief Status Macro + * This macros aims at capturing abnormal errors in the FWIMG sub-module (typically FLASH errors). + * When SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is activated this macro blocks the execution. + * When SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE is deactivated, a log is printed in the console (if SFU_DEBUG_MODE is + * activated) and the execution continues. + */ +#if defined(SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE) +#define STATUS_FWIMG(B,A) if (B) { \ + SFU_IMG_Status=A; \ + SFU_IMG_Line = __LINE__; \ + TRACE("\r\n Abnormal error %d at line %d in %s - BLOCK", \ + SFU_IMG_Status, SFU_IMG_Line, __FILE__); \ + while(1==1){;} \ + } while(0==1){;} +#else +#define STATUS_FWIMG(B,A) if (B) { \ + SFU_IMG_Status=A; \ + SFU_IMG_Line = __LINE__; \ + TRACE("\r\n Abnormal error %d at line %d in %s - CONTINUE", \ + SFU_IMG_Status, SFU_IMG_Line, __FILE__); \ + } while(0==1){;} +#endif /* SFU_FWIMG_BLOCK_ON_ABNORMAL_ERRORS_MODE */ + +/* External variables --------------------------------------------------------*/ +/** + * FWIMG status variables used to log errors and display debug messages. + * This is related to FLASH operations. + * This is handled with STATUS_FWIMG. + */ +extern SFU_IMG_StatusTypeDef SFU_IMG_Status; +extern uint32_t SFU_IMG_Line; + +extern SE_FwRawHeaderTypeDef fw_image_header_validated; +extern SE_FwRawHeaderTypeDef fw_image_header_to_test; + +/* Exported functions : helper ---------------------------------------------- */ +SFU_ErrorStatus MemoryCompare(uint8_t *pAdd1, uint8_t *pAdd2, uint32_t Size); +SFU_ErrorStatus VerifyHeaderSignature(SE_FwRawHeaderTypeDef *pFwImageHeader); +SFU_ErrorStatus VerifyFwSignatureScatter(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, + SE_FwRawHeaderTypeDef *pSE_Metadata, + SE_Ex_PayloadDescTypeDef *pSE_Payload, uint32_t SE_FwType); +SFU_ErrorStatus VerifyTag(SE_StatusTypeDef *pSeStatus, uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pSE_Metadata, + uint8_t *pPayload, uint32_t SE_FwType); +SFU_ErrorStatus ParseFWInfo(SE_FwRawHeaderTypeDef *pFwHeader, uint8_t *pBuffer); +SFU_ErrorStatus CheckAndGetFWHeader(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFwImageHeader); +SFU_ErrorStatus VerifyFwSignature(SE_StatusTypeDef *pSeStatus, uint32_t slot, SE_FwRawHeaderTypeDef *pFwImageHeader, + uint32_t SE_FwType); +SFU_ErrorStatus VerifySlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uFwSize); +SFU_ErrorStatus CleanUpSlot(uint8_t *pSlotBegin, uint32_t uSlotSize, uint32_t uOffset); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_FWIMG_INTERNAL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_no_swap.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_no_swap.c new file mode 100644 index 00000000..f0fe88d5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_no_swap.c @@ -0,0 +1,919 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_no_swap.c + * @author MCD Application Team + * @brief This file provides set of firmware functions to manage the Firmware Images. + * This file contains the specific functionalities of the image handling for + * the installation process without swap area. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_FWIMG_NO_SWAP_C + +/* Includes ------------------------------------------------------------------*/ +#include +#include "main.h" +#include "sfu_fsm_states.h" /* needed for sfu_error.h */ +#include "sfu_error.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "se_interface_bootloader.h" +#include "sfu_interface_crypto_scheme.h" +#include "sfu_fwimg_regions.h" +#include "sfu_fwimg_services.h" +#include "sfu_fwimg_internal.h" +#include "sfu_trace.h" +#include "sfu_boot.h" + + +#if defined(SFU_NO_SWAP) +/* Private macros ------------------------------------------------------------*/ +#define TRAILER_HEADER (SE_FW_HEADER_TOT_LEN + SE_FW_HEADER_TOT_LEN + MAGIC_LENGTH) + +/* DWL_SLOT_REGION_SIZE */ +/* <------------------------------------------> */ +/* |HEADER_TOT_LEN|HEADER_TOT_LEN|MAGIC_LENGTH| */ +/* | header 1 | header 2 |SWAP magic | */ + +#define TRAILER_BEGIN(A) (( uint8_t *)(SlotStartAdd[A] + SLOT_SIZE(A) - TRAILER_HEADER)) +#define TRAILER_HDR_VALID(A) ((uint8_t *)(TRAILER_BEGIN(A))) +#define TRAILER_HDR_TEST(A) ((uint8_t *)(TRAILER_BEGIN(A) + SE_FW_HEADER_TOT_LEN)) +#define TRAILER_SWAP_ADDR(A) ((uint8_t *)(TRAILER_BEGIN(A) + SE_FW_HEADER_TOT_LEN + SE_FW_HEADER_TOT_LEN)) + +#endif /* defined(SFU_NO_SWAP) */ + +/* Functions Definition : helper ---------------------------------------------*/ +#if defined(SFU_NO_SWAP) + +/** + * @brief Write Trailer Headers : TEST + VALID + SWAP + * @param DwlSlot identification of the downloaded area + * @param pValidHeader: pointer in ram to header of valid fw to backup + * @param pTestHeader: pointer in ram to header of fw to test + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus WriteTrailerHeader(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pValidHeader, + SE_FwRawHeaderTypeDef *pTestHeader) +{ + /* everything is in place , just compute from present data and write it */ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_info; + uint8_t magic[MAGIC_LENGTH]; + uint32_t buffer; + + /* Write Headers VALID + TEST */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, TRAILER_HDR_TEST(DwlSlot), (uint8_t *) pTestHeader, + SE_FW_HEADER_TOT_LEN); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, TRAILER_HDR_VALID(DwlSlot), (uint8_t *) pValidHeader, + SE_FW_HEADER_TOT_LEN); + } + + /* Write Magic */ + if (e_ret_status == SFU_SUCCESS) + { + buffer = (uint32_t) pValidHeader; + (void) memcpy(&magic[0U], (uint8_t *)(buffer + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), MAGIC_LENGTH / 2U); + buffer = (uint32_t) pTestHeader; + (void) memcpy(&magic[MAGIC_LENGTH / 2U], (uint8_t *)(buffer + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), + MAGIC_LENGTH / 2U); + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, TRAILER_SWAP_ADDR(DwlSlot), magic, MAGIC_LENGTH); + } + + return e_ret_status; +} + +/** + * @brief Check the magic from trailer or counter + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus CheckTrailerMagic(uint32_t DwlSlot) +{ + uint8_t magic[MAGIC_LENGTH]; + uint8_t signature_valid[MAGIC_LENGTH / 2]; + uint8_t signature_test[MAGIC_LENGTH / 2]; + uint8_t erased_flash_pattern[MAGIC_LENGTH]; + + /* Pattern initialization */ + (void) memset(erased_flash_pattern, 0xFF, MAGIC_LENGTH); + + /* Read trailer fields : TRAILER_HDR_VALID, TRAILER_HDR_TEST, MAGIC, CLEAN */ + if (SFU_LL_FLASH_Read(signature_valid, + (uint8_t *)((uint32_t)TRAILER_HDR_VALID(DwlSlot) + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), + sizeof(signature_valid)) != SFU_SUCCESS) + { + return SFU_ERROR; + } + if (SFU_LL_FLASH_Read(signature_test, + (uint8_t *)((uint32_t) TRAILER_HDR_TEST(DwlSlot) + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), + sizeof(signature_test)) != SFU_SUCCESS) + { + return SFU_ERROR; + } + if (SFU_LL_FLASH_Read(magic, TRAILER_SWAP_ADDR(DwlSlot), MAGIC_LENGTH) != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* + * Check magic validity : + * - last 16 bytes of validated header + * - last 16 bytes of test header + * - significant values (not an erased flash pattern) + */ + if ((memcmp(magic, signature_valid, sizeof(signature_valid)) != 0) + || (memcmp(&magic[MAGIC_LENGTH / 2U], signature_test, sizeof(signature_test)) != 0) + || (memcmp(magic, erased_flash_pattern, MAGIC_LENGTH) == 0)) + { + return SFU_ERROR; + } + return SFU_SUCCESS; +} + +/** + * @brief check trailer validity to allow resume installation. + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @param pValidHeader: pointer in ram to header of valid fw to backup + * @param pTestHeader: pointer in ram to header of fw to test + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus FirmwareToResume(uint32_t ActiveSlot, uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pValidHeader, + SE_FwRawHeaderTypeDef *pTestHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t fw_header_trailer_valid[SE_FW_HEADER_TOT_LEN]; + uint8_t fw_header_trailer_test[SE_FW_HEADER_TOT_LEN]; + uint8_t fw_header_active_slot[SE_FW_HEADER_TOT_LEN]; + uint8_t fw_header_dwl_slot[SE_FW_HEADER_TOT_LEN]; + + /* + * Initial conditions to be fulfilled : + * - Trailer magic is present + * - Active slot number is correct + * - test header from trailer is signed + * - header from dwl slot is same as the one from trailer + */ + + /* check trailer Magic */ + e_ret_status = CheckTrailerMagic(DwlSlot); + if (e_ret_status == SFU_SUCCESS) + { + /* Populate the pTestHeader and verify it the active slot is correct */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_trailer_test, TRAILER_HDR_TEST(DwlSlot), sizeof(fw_header_trailer_test)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Populate pTestHeader parameter */ + e_ret_status = ParseFWInfo(pTestHeader, fw_header_trailer_test); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Active slot number correct ? + As example : if magic is SFU2 active slot should be SLOT_ACTIVE_2 */ + if (ActiveSlot == SFU_IMG_GetFwImageSlot(pTestHeader)) + { + /* Check header test field in trailer is signed */ + e_ret_status = VerifyHeaderSignature((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header_trailer_test); + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t No resume required : TRAILER_HDR_TEST not valid!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + e_ret_status = SFU_ERROR; + } + } + + /* Read header from dwl slot and verify this is the same as the test header from trailer */ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Read(fw_header_dwl_slot, (uint8_t *) SlotStartAdd[DwlSlot], + sizeof(fw_header_dwl_slot)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (memcmp(fw_header_dwl_slot, fw_header_trailer_test, SE_FW_AUTH_LEN) != 0U) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t No resume required : TRAILER_HDR_TEST not same as dwl slot header!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + e_ret_status = SFU_ERROR; + } + } + + /* First part KO : return error */ + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* Read header in active slot if any */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_active_slot, (uint8_t *) SlotHeaderAdd[ActiveSlot], + sizeof(fw_header_active_slot)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + + if (e_ret_status == SFU_SUCCESS) + { + /* Verify the header signature in active slot */ + e_ret_status = VerifyHeaderSignature((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header_active_slot); + } + if (e_ret_status == SFU_SUCCESS) + { + /* Header in active slot is signed and validated, in protected area: it can be trusted. */ + + /* Populate pValidHeader parameter */ + e_ret_status = ParseFWInfo(pValidHeader, fw_header_active_slot); + + if (e_ret_status == SFU_SUCCESS) + { + /* Read header valid field in trailer */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_trailer_valid, TRAILER_HDR_VALID(DwlSlot), + sizeof(fw_header_trailer_valid)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* + * 3 cases: + * - Header in active slot is identical to the header valid field + * ==> installation interrupted very early. Resume install must be triggered. + * - Header in active slot is identical to the header test field + * ==> installation interrupted after active header erasing. Resume install must be triggered. + * - Any other values + * ==> Hack tentative, resume install must not be triggered. + */ + + /* Check if header in active slot is same as header valid in trailer */ + if (memcmp(fw_header_active_slot, fw_header_trailer_valid, SE_FW_AUTH_LEN) != 0) + { + /* Check candidate image version : should be OK */ + e_ret_status = SFU_IMG_CheckFwVersion(ActiveSlot, pValidHeader->FwVersion, pTestHeader->FwVersion); + } + /* Check if header in active slot is same as header test in trailer */ + else if (memcmp(fw_header_active_slot, fw_header_trailer_test, SE_FW_AUTH_LEN) == 0U) + { + e_ret_status = SFU_SUCCESS; + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t No resume required : Header in active slot is neither sames TRAILER_HDR_TEST as nor TRAILER_VALID_TEST!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + e_ret_status = SFU_ERROR; + } + } + /* At this point, if (e_ret_status == SFU_SUCCESS) then resume of installation is allowed */ + } + else + { + /* + * Header in active slot is not valid. + * It is considered this can not be hack attempt, because header in active slot is in + * protected area. + * Possible reasons: + * - Installation has been interrupted during very first image installation (active slot was empty) + * - Installation has been interrupted during reconstitution of first sector of active slot + * If header test field in trailer is signed and with proper version, we resume install. + */ + + /* Read header valid field in trailer */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_trailer_valid, TRAILER_HDR_VALID(DwlSlot), + sizeof(fw_header_trailer_valid)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (e_ret_status == SFU_SUCCESS) + { + /* Check header valid field in trailer is signed */ + e_ret_status = VerifyHeaderSignature((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header_trailer_valid); + + if (e_ret_status == SFU_SUCCESS) + { + /* active slot was containing an active image */ + + /* Populate pValidHeader parameter */ + e_ret_status = ParseFWInfo(pValidHeader, fw_header_trailer_valid); + + if (e_ret_status == SFU_SUCCESS) + { + /* Check candidate image version */ + e_ret_status = SFU_IMG_CheckFwVersion(ActiveSlot, pValidHeader->FwVersion, pTestHeader->FwVersion); + } + } + else + { + /* active slot was empty : we authorize only the installation of a specific version identified by + SFU_FW_VERSION_INIT_NUM */ + if (pTestHeader->FwVersion == SFU_FW_VERSION_INIT_NUM) + { + /* active slot was empty or was containing bricked Fw image */ + e_ret_status = SFU_SUCCESS; + } +#if defined(SFU_VERBOSE_DEBUG_MODE) + else + { + TRACE("\r\n\t Init version:%d - Candidate version:%d : Installation not allowed!", SFU_FW_VERSION_INIT_NUM, pTestHeader->FwVersion); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + + /* At this point, if (e_ret_status == SFU_SUCCESS) then resume of installation is allowed */ + } + + return e_ret_status; +} + +/** + * @brief Verify signature on encrypted FW + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer to fw header + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus VerifyFwSignatureBeforeDecrypt(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + SE_ErrorStatus se_ret_status; + uint8_t fw_encrypted_chunk[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + uint8_t fw_decrypted_chunk[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + uint32_t fw_decrypted_chunk_size; +#if (SECBOOT_CRYPTO_SCHEME != SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + uint8_t fw_authenticated_chunk[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + uint32_t fw_authenticated_chunk_size; +#endif /* (SECBOOT_CRYPTO_SCHEME != SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) */ + uint32_t fw_index; + uint32_t size; + uint32_t fw_tag_len; + uint8_t fw_tag_output[SE_TAG_LEN]; + + /* Verify header presence */ + if ((pFwImageHeader == NULL)) + { + return e_ret_status; + } + + /* Decryption process initialization + ================================= */ + se_ret_status = SE_Decrypt_Init(&e_se_status, pFwImageHeader, SE_FW_IMAGE_COMPLETE); + if (se_ret_status == SE_SUCCESS) + { +#if (SECBOOT_CRYPTO_SCHEME != SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + se_ret_status = SE_AuthenticateFW_Init(&e_se_status, pFwImageHeader, SE_FW_IMAGE_COMPLETE); +#endif /* (SECBOOT_CRYPTO_SCHEME != SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) */ + + /* Skip header : no decryption needed */ + fw_index = SFU_IMG_IMAGE_OFFSET; + + e_ret_status = SFU_SUCCESS; + while ((e_ret_status == SFU_SUCCESS) && (se_ret_status == SE_SUCCESS) && + (fw_index < (pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET))) + { + /* Set size of reading/decryption */ + size = SFU_IMG_CHUNK_SIZE; + + /* Last pass ? */ + if (((pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET) - fw_index) < size) + { + /* Default chunk size can be troncated at end of file */ + size = pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET - fw_index; + } + + /* read then decrypt phase + ======================= */ + e_ret_status = SFU_LL_FLASH_Read(fw_encrypted_chunk, (uint8_t *)(SlotStartAdd[DwlSlot] + fw_index), size); + if (e_ret_status == SFU_SUCCESS) + { + fw_decrypted_chunk_size = size; + se_ret_status = SE_Decrypt_Append(&e_se_status, fw_encrypted_chunk, (int32_t)size, fw_decrypted_chunk, + (int32_t *)&fw_decrypted_chunk_size); + + if (se_ret_status == SE_SUCCESS) + { +#if (SECBOOT_CRYPTO_SCHEME != SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + fw_authenticated_chunk_size = sizeof(fw_authenticated_chunk); + se_ret_status = SE_AuthenticateFW_Append(&e_se_status, fw_decrypted_chunk, (int32_t)size, + fw_authenticated_chunk, (int32_t *)&fw_authenticated_chunk_size); +#endif /* (SECBOOT_CRYPTO_SCHEME != SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) */ + fw_index += size; + } + } + } + } + + /* Do the Finalization, check the authentication TAG + ================================================= */ + if ((se_ret_status == SE_SUCCESS) && (e_ret_status == SFU_SUCCESS)) + { + e_ret_status = SFU_ERROR; + + /* Finalization stage */ + fw_tag_len = sizeof(fw_tag_output); + se_ret_status = SE_Decrypt_Finish(&e_se_status, fw_tag_output, (int32_t *)&fw_tag_len); + if (se_ret_status == SE_SUCCESS) + { +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + e_ret_status = SFU_SUCCESS; +#else + fw_tag_len = sizeof(fw_tag_output); + se_ret_status = SE_AuthenticateFW_Finish(&e_se_status, fw_tag_output, (int32_t *)&fw_tag_len); + if ((se_ret_status == SE_SUCCESS) && (fw_tag_len == SE_TAG_LEN)) + { + /* Firmware tag verification */ + if (MemoryCompare(fw_tag_output, pFwImageHeader->FwTag, SE_TAG_LEN) == SFU_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + } + } +#endif /* (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) */ + } + } + else + { + e_ret_status = SFU_ERROR; + } + + return e_ret_status; +} + +/** + * @brief Decrypt Image from dwl slot to active slot + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer to fw header + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus DecryptImageFromDwlSlotToActiveSlot(uint32_t ActiveSlot, uint32_t DwlSlot, + SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + SE_ErrorStatus se_ret_status; + SFU_FLASH_StatusTypeDef flash_if_status; + uint8_t fw_encrypted_chunk[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + uint8_t fw_decrypted_chunk[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + uint32_t fw_index; + uint32_t size; + uint32_t fw_decrypted_chunk_size; + uint32_t fw_tag_len; + uint8_t fw_tag_output[SE_TAG_LEN]; + + TRACE("\r\n\t Image preparation done.\r\n\t Installation started ..."); + + /* Verify header presence */ + if ((pFwImageHeader == NULL)) + { + return e_ret_status; + } + + /* Control the firwmare size vs slot size */ + if ((pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET) > SLOT_SIZE(ActiveSlot)) + { + return e_ret_status; + } + + /* Decryption process initialization + ================================= */ + se_ret_status = SE_Decrypt_Init(&e_se_status, pFwImageHeader, SE_FW_IMAGE_COMPLETE); + if (se_ret_status == SE_SUCCESS) + { + + /* Erasing operation + ================= */ + + /* + * The header may not be contiguous with the FW image : 2 erasing operations needed + */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotHeaderAdd[ActiveSlot], + SFU_IMG_IMAGE_OFFSET); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, + (uint8_t *)(SlotStartAdd[ActiveSlot] + SFU_IMG_IMAGE_OFFSET), + SLOT_SIZE(ActiveSlot) - SFU_IMG_IMAGE_OFFSET); + } + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + /* + * Save immediately the new active FW header + */ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_IMG_Validation(ActiveSlot, pFwImageHeader); + if (e_ret_status != SFU_SUCCESS) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Header writing failure!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + + /* + * Skip header : no decryption needed + */ + fw_index = SFU_IMG_IMAGE_OFFSET; + + while ((e_ret_status == SFU_SUCCESS) && (se_ret_status == SE_SUCCESS) && + (fw_index < (pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET))) + { + /* Refresh Watchdog every 10 iterations */ + if ((fw_index % 10U) != 0U) + { + (void) SFU_LL_SECU_IWDG_Refresh(); + } + + /* Set size of reading/decryption */ + size = SFU_IMG_CHUNK_SIZE; + + /* Last pass ? */ + if (((pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET) - fw_index) < size) + { + /* Default chunk size can be troncated at end of file */ + size = pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET - fw_index; + } + + /* read then decrypt phase + ======================= */ + e_ret_status = SFU_LL_FLASH_Read(fw_encrypted_chunk, (uint8_t *)(SlotStartAdd[DwlSlot] + fw_index), size); + if (e_ret_status == SFU_SUCCESS) + { + fw_decrypted_chunk_size = size; + se_ret_status = SE_Decrypt_Append(&e_se_status, fw_encrypted_chunk, (int32_t)size, fw_decrypted_chunk, + (int32_t *)&fw_decrypted_chunk_size); + + /* + * writing phase + * =============== */ + if (se_ret_status == SE_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *)(SlotStartAdd[ActiveSlot] + fw_index), + fw_decrypted_chunk, size); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + + /* Update pointer */ + fw_index += size; + } + } + } + } + +#if (SFU_IMAGE_PROGRAMMING_TYPE == SFU_ENCRYPTED_IMAGE) +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t %d bytes of ciphertext decrypted.", fw_index); +#endif /* SFU_VERBOSE_DEBUG_MODE */ +#endif /* SFU_ENCRYPTED_IMAGE */ + + if ((se_ret_status == SE_SUCCESS) && (e_ret_status == SFU_SUCCESS)) + { + /* Do the Finalization, check the authentication TAG*/ + fw_tag_len = sizeof(fw_tag_output); + se_ret_status = SE_Decrypt_Finish(&e_se_status, fw_tag_output, (int32_t *)&fw_tag_len); + if (se_ret_status != SE_SUCCESS) + { + e_ret_status = SFU_ERROR; +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Decrypt fails at Finalization stage."); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + } + else + { + e_ret_status = SFU_ERROR; + } + return e_ret_status; +} + + +/** + * @brief Install the new version + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @param pValidHeader: pointer in ram to header of valid fw to backup + * @param pTestHeader: pointer in ram to header of fw to test + * @retval SFU_SUCCESS if successful,SFU_ERROR error otherwise. + */ +static SFU_ErrorStatus InstallNewVersion(uint32_t ActiveSlot, uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pValidHeader, + SE_FwRawHeaderTypeDef *pTestHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef x_flash_info; + + /* + * Verify FW Image signature in dwl slot + */ + e_ret_status = VerifyFwSignatureBeforeDecrypt(DwlSlot, pTestHeader); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_SIGNATURE_ERR); + return e_ret_status; + } + + /* + * Control if there is no additional code beyond the firmware image (malicious SW) + */ + e_ret_status = VerifySlot((uint8_t *) SlotStartAdd[DwlSlot], SLOT_SIZE(DwlSlot), pTestHeader->FwSize); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_ADDITIONAL_CODE_ERR); + return e_ret_status; + } + + /* + * Write trailer : memorize installation process started + */ + e_ret_status = WriteTrailerHeader(DwlSlot, pValidHeader, pTestHeader); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_TRAILER_UPDATE_ERR); + return e_ret_status; + } + + /* + * Decrypt the FW image : from dwl slot to active slot + */ + e_ret_status = DecryptImageFromDwlSlotToActiveSlot(ActiveSlot, DwlSlot, pTestHeader); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_DECRYPT_ERR); + return e_ret_status; + } + + + /* + * erase downloaded FW after installation + */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) SlotStartAdd[DwlSlot], SLOT_SIZE(DwlSlot)); + if (e_ret_status != SFU_SUCCESS) + { + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + SFU_EXCPT_SetError(SFU_EXCPT_DWL_SLOT_ERASING_ERR); + return e_ret_status; + } + + return (e_ret_status); +} + +/** + * @brief Check that there is an Image to Install + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer to fw header to be populated + * @retval SFU_SUCCESS if Image can be installed, a SFU_ERROR otherwise. + */ +static SFU_ErrorStatus FirmwareToInstall(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t trailer_begin = (uint32_t) TRAILER_BEGIN(DwlSlot); + uint32_t end_of_test_image; + + /* Verify FW Image Header tag in dwl slot */ + e_ret_status = CheckAndGetFWHeader(DwlSlot, pFwImageHeader); + if (e_ret_status == SFU_SUCCESS) + { + end_of_test_image = (SlotStartAdd[DwlSlot] + pFwImageHeader->FwSize + + SFU_IMG_IMAGE_OFFSET); + + /* Check if there is enough room for the trailers */ + if (trailer_begin < end_of_test_image) + { + /* + * This error causes is not memorized in the BootInfo area because there won't be any error handling + * procedure. + * If this function returns that no new firmware can be installed (as this may be a normal case). + */ + e_ret_status = SFU_ERROR; + +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t The binary image to be installed overlap with the trailer area!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + else + { + e_ret_status = SFU_SUCCESS; + } + } + + return e_ret_status; +} + +#endif /* (SFU_NO_SWAP) */ + + + +/* Functions Definition : services ------------------------------------------- */ + +#if defined(SFU_NO_SWAP) +/** + * @brief Checks if there is a pending firmware installation. + * 2 situations can occur: + * A. Pending firmware installation: a firmware is ready to be installed. + * B. No firmware installation pending + * @note The anti-rollback check is not taken into account at this stage. + * @note This function populates the FWIMG module variables: fw_image_header_to_test + * @param pDwlSlotToInstall identification of the downloaded slot to install + * @param pActiveSlotToResume identification of the active slot to resume + * @param pActiveSlotToRollback identification of the active slot to rollback + * @retval SFU_IMG_ImgInstallStateTypeDef Pending Installation status (pending install, no pending action) + */ +SFU_IMG_ImgInstallStateTypeDef SFU_IMG_CheckPendingInstallation(uint32_t *pDwlSlotToInstall, \ + uint32_t *pActiveSlotToResume, \ + uint32_t *pActiveSlotToRollback) +{ + SFU_IMG_ImgInstallStateTypeDef e_ret_state = SFU_IMG_NO_FWUPDATE; + uint32_t i; + uint32_t j; + + /* No rollback capability in "NO_SWAP" configuration */ + *pActiveSlotToResume = SLOT_INACTIVE; + *pActiveSlotToRollback = SLOT_INACTIVE; + *pDwlSlotToInstall = SLOT_INACTIVE; + + /* Check image installation stopped + ================================ */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + for (j = 0U; j < SFU_NB_MAX_DWL_AREA; j++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_DWL_1 + j] != 0U) + { + if (SFU_SUCCESS == FirmwareToResume(SLOT_ACTIVE_1 + i, SLOT_DWL_1 + j, &fw_image_header_validated, + &fw_image_header_to_test)) + { + /* A Firmware Update has been stopped + * fw_image_header_to_test & fw_image_header_validated have been populated + * Stop at first occurrence : next ones if any will be resumed after reset + */ + *pActiveSlotToResume = SLOT_ACTIVE_1 + i; + *pDwlSlotToInstall = SLOT_DWL_1 + j; + return SFU_IMG_FWUPDATE_STOPPED; + } + } + } + } + } + + /* Install new firmware if requested + ================================= */ + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_DWL_1 + i] != 0U) + { + if (SFU_SUCCESS == FirmwareToInstall(SLOT_DWL_1 + i, &fw_image_header_to_test)) + { + /* + * A Firmware is available for installation: + * fw_image_header_to_test has been populated + * Stop at first occurrence : next ones if any will be installed after reset + */ + *pDwlSlotToInstall = SLOT_DWL_1 + i; + return SFU_IMG_FWIMAGE_TO_INSTALL; + } + } + } + + return e_ret_state; +} + +/** + * @brief Resume installation : not required but present for compatibility with swap process + * If installation procedure is interrupted (e.g.: switch off) it will be restarted from begin at next reboot. + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS + */ +SFU_ErrorStatus SFU_IMG_TriggerResumeInstallation(uint32_t ActiveSlot, uint32_t DwlSlot) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef x_flash_info; + + /* + * Decrypt the FW image : from dwl slot to active slot + */ + e_ret_status = DecryptImageFromDwlSlotToActiveSlot(ActiveSlot, DwlSlot, &fw_image_header_to_test); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_DECRYPT_ERR); + } + + /* + * erase downloaded FW after installation + */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) SlotStartAdd[DwlSlot], SLOT_SIZE(DwlSlot)); + if (e_ret_status != SFU_SUCCESS) + { + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + SFU_EXCPT_SetError(SFU_EXCPT_DWL_SLOT_ERASING_ERR); + } + +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status == SFU_SUCCESS) + { + TRACE("\r\n\t Resume procedure completed."); + } + else + { + TRACE("\r\n\t Resume procedure cannot be finalized!"); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + return (e_ret_status); +} + +/** + * @brief Installs a new firmware, performs the post-installation checks and sets the metadata to tag this firmware as + * valid if the checks are successful. + * Cryptographic operations are used (if enabled): the firmware is decrypted and its authenticity is checked + * afterwards if the cryptographic scheme allows this (signature check for instance). + * The detailed errors are memorized in bootinfo area to be processed as critical errors if needed. + * This function modifies the FLASH content. + * If this procedure is interrupted (e.g.: switch off) installation will be restarted from begin at next reboot. + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_TriggerImageInstallation(uint32_t DwlSlot) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t *pbuffer; + uint32_t active_slot; + + active_slot = SFU_IMG_GetFwImageSlot(&fw_image_header_to_test); + + /* + * Populate fw_image_header_validated + */ + pbuffer = (uint8_t *) SlotHeaderAdd[active_slot]; + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &fw_image_header_validated, pbuffer, + sizeof(fw_image_header_validated)); + + /* + * Installing the new firmware image consists in decrypting the candidate firmware image. + * fw_image_header_to_test is already populated after SFU_IMG_CheckPendingInstallation() call. + */ + if (SFU_SUCCESS == e_ret_status) + { + e_ret_status = InstallNewVersion(active_slot, DwlSlot, &fw_image_header_validated, &fw_image_header_to_test); + } + + if (SFU_SUCCESS != e_ret_status) + { + /* Erase downloaded FW in case of installation error */ + (void) SFU_IMG_EraseDownloadedImg(DwlSlot); + } + +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status == SFU_SUCCESS) + { + TRACE("\r\n\t Installation procedure completed."); + } + else + { + TRACE("\r\n\t Installation procedure cannot be finalized!"); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + /* return the installation result */ + return (e_ret_status); +} +#endif /* (SFU_NO_SWAP) */ + + +#if defined(SFU_NO_SWAP) +/** + * @brief Erase downloaded firmware in case of decryption/authentication/integrity error + * @param DwlSlot identification of the downloaded area + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus SFU_IMG_EraseDownloadedImg(uint32_t DwlSlot) +{ + SFU_FLASH_StatusTypeDef flash_if_status; + SFU_ErrorStatus e_ret_status_dwl = SFU_ERROR; + + e_ret_status_dwl = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotStartAdd[DwlSlot], + SLOT_SIZE(DwlSlot)); + STATUS_FWIMG(e_ret_status_dwl == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + return ((e_ret_status_dwl != SFU_SUCCESS) ? SFU_ERROR : SFU_SUCCESS); +} + +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) || (SFU_NO_SWAP) */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_regions.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_regions.h new file mode 100644 index 00000000..0408a5ee --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_regions.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_regions.h + * @author MCD Application Team + * @brief This file contains FLASH regions definitions for SFU_FWIMG functionalities + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_FWIMG_REGIONS_H +#define SFU_FWIMG_REGIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "app_sfu.h" +#if defined(__ARMCC_VERSION) +#include "mapping_fwimg.h" +#elif defined (__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __ARMCC_VERSION */ +#include "se_crypto_config.h" + + +/* Exported constants --------------------------------------------------------*/ +/** + * Slot list : 2 slots per image configuration + swap + */ +#define NB_SLOTS 4U +#define SLOT_INACTIVE 0U /* this index should not be used ==> no tag found in the header */ +#define SLOT_ACTIVE_1 1U +#define SLOT_DWL_1 2U +#define SLOT_SWAP 3U + +/* Calculation of the size of a slot */ +#define SLOT_SIZE(a) (SlotEndAdd[a] - SlotStartAdd[a] + 1U) + +/* + * Design constraint: the image slot size must be a multiple of the swap area size. + * And of course both image slots must have the same size. + */ +#define SFU_IMG_REGION_IS_MULTIPLE(a,b) ((a / b * b) == a) + +/* + * Checking that the slot sizes are consistent with the .icf file + * Sizes expressed in bytes (+1 because the end address belongs to the slot) + * The checks are executed at runtime in the SFU_Img_Init() function. + */ +#define SFU_IMG_REGION_IS_SAME_SIZE(a,b) ((a) == (b)) + +/** + * Image starting offset to add to the address of 1st block + */ +#define SFU_IMG_IMAGE_OFFSET ((uint32_t)512U) + + +/* External variables --------------------------------------------------------*/ +extern const uint32_t SlotHeaderAdd[NB_SLOTS]; +extern const uint32_t SlotStartAdd[NB_SLOTS]; +extern const uint32_t SlotEndAdd[NB_SLOTS]; + +#if (defined(SFU_FWIMG_COMMON_C) || defined(SE_LOW_LEVEL_C) || defined(TEST_PROTECTIONS_C)) + +const uint32_t SlotHeaderAdd[NB_SLOTS] = { 0U, + SLOT_ACTIVE_1_HEADER, + SLOT_DWL_1_START, + SWAP_START, + }; +/* List of slot start address */ +const uint32_t SlotStartAdd[NB_SLOTS] = { 0U, + SLOT_ACTIVE_1_START, + SLOT_DWL_1_START, + SWAP_START, + }; +/* List of slot end address */ +const uint32_t SlotEndAdd[NB_SLOTS] = { 0U, + SLOT_ACTIVE_1_END, + SLOT_DWL_1_END, + SWAP_END, + }; +#endif /* SFU_FWIMG_COMMON_C || SE_LOW_LEVEL_C || TEST_PROTECTIONS_C || SFU_LOADER_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_FWIMG_REGIONS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_services.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_services.h new file mode 100644 index 00000000..4d127d81 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_services.h @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_services.h + * @author MCD Application Team + * @brief This file contains the 2 images handling service (SFU_FWIMG functionalities) + * API definitions. + * These services can be called by the bootloader to deal with images handling. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_FWIMG_SERVICES_H +#define SFU_FWIMG_SERVICES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "se_def.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief SFU_IMG Initialization Status Type Definition + */ +typedef enum +{ + SFU_IMG_INIT_OK = 0x0U, /*!< SFU Firmware Image Handling (FWIMG) Init OK */ + SFU_IMG_INIT_SLOTS_SIZE_ERROR, /*!< error related to slots size */ + SFU_IMG_INIT_SWAP_SETTINGS_ERROR, /*!< error related to swap settings */ + SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR, /*!< error related to flash constraints */ + SFU_IMG_INIT_CRYPTO_CONSTRAINTS_ERROR, /*!< error related to crypto constraints */ + SFU_IMG_INIT_ERROR /*!< Init is FAILED: unspecified error */ +} SFU_IMG_InitStatusTypeDef; + +/** + * @brief SFU_IMG Image Installation State Type Definition + */ +typedef enum +{ + SFU_IMG_FWIMAGE_TO_INSTALL = 0x0U, /*!< There is a FW image to be installed */ + SFU_IMG_FWUPDATE_STOPPED, /*!< A previous installation has been interrupted before it completed : resume installation */ + SFU_IMG_NO_FWUPDATE, /*!< No FW image installation pending */ + SFU_IMG_FWIMAGE_ROLLBACK, /*!< A new FW image installation has not been validated : rollback initiated @ next reset */ +} SFU_IMG_ImgInstallStateTypeDef; + +/* Exported functions ------------------------------------------------------- */ +SFU_IMG_InitStatusTypeDef SFU_IMG_InitImageHandling(void); +SFU_IMG_InitStatusTypeDef SFU_IMG_CheckSwapImageHandling(void); +SFU_IMG_ImgInstallStateTypeDef SFU_IMG_CheckPendingInstallation(uint32_t *pDwlSlotToInstall, \ + uint32_t *pActiveSlotToResume, \ + uint32_t *pActiveSlotToRollback); +SFU_ErrorStatus SFU_IMG_CheckCandidateVersion(uint32_t DwlSlot); +SFU_ErrorStatus SFU_IMG_TriggerImageInstallation(uint32_t DwlSlot); +SFU_ErrorStatus SFU_IMG_TriggerResumeInstallation(uint32_t ActiveSlot, uint32_t DwlSlot); +#ifdef ENABLE_IMAGE_STATE_HANDLING +SFU_ErrorStatus SFU_IMG_TriggerRollbackInstallation(uint32_t ActiveSlot, uint32_t DwlSlot); +SFU_ErrorStatus SFU_IMG_UpdateImageState(uint32_t SlotNumber); +#endif /* ENABLE_IMAGE_STATE_HANDLING */ +SFU_ErrorStatus SFU_IMG_EraseDownloadedImg(uint32_t DwlSlot); +uint32_t SFU_IMG_GetTrailerSize(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_InvalidateCurrentFirmware(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyActiveImgMetadata(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyActiveImg(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyActiveSlot(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_VerifyEmptyActiveSlot(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_LaunchActiveImg(uint32_t SlotNumber); +uint16_t SFU_IMG_GetActiveFwVersion(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_DetectFW(uint32_t SlotNumber); +SFU_ErrorStatus SFU_IMG_Validation(uint32_t SlotNumber, SE_FwRawHeaderTypeDef *pFWImageHeader); +SFU_ErrorStatus SFU_IMG_ControlActiveImgTag(uint32_t SlotNumber); +uint32_t SFU_IMG_GetFwImageSlot(SE_FwRawHeaderTypeDef *pFwImageHeader); +SFU_ErrorStatus SFU_IMG_CheckFwVersion(uint32_t ActiveSlot, uint16_t CurrentVersion, uint16_t CandidateVersion); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_FWIMG_SERVICES_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_swap.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_swap.c new file mode 100644 index 00000000..e2200b32 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_fwimg_swap.c @@ -0,0 +1,2317 @@ +/** + ****************************************************************************** + * @file sfu_fwimg_swap.c + * @author MCD Application Team + * @brief This file provides set of firmware functions to manage the Firmware Images. + * This file contains the specific functionalities of the image handling for + * the installation process with swap area. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_FWIMG_SWAP_C + +/* Includes ------------------------------------------------------------------*/ +#include +#include "main.h" +#include "sfu_fsm_states.h" /* needed for sfu_error.h */ +#include "sfu_error.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "se_interface_bootloader.h" +#include "sfu_interface_crypto_scheme.h" +#include "sfu_fwimg_regions.h" +#include "sfu_fwimg_services.h" /* to have definitions like SFU_IMG_InitStatusTypeDef + (required by sfu_fwimg_internal.h) */ +#include "sfu_fwimg_internal.h" +#include "sfu_trace.h" +#include "sfu_boot.h" + +#if !defined(SFU_NO_SWAP) + +/* Private macros ------------------------------------------------------------*/ +#define TRAILER_INDEX(A) (SLOT_SIZE(A) / SLOT_SIZE(SLOT_SWAP)) +/* position of image begin on 1st block */ +#define TRAILER_HEADER (SE_FW_HEADER_TOT_LEN + SE_FW_HEADER_TOT_LEN + MAGIC_LENGTH + MAGIC_LENGTH) + +/* DWL_SLOT_REGION_SIZE */ +/* <-----------------------------------------------------------------------------------------------------> */ +/* |HEADER_TOT_LEN|HEADER_TOT_LEN|MAGIC_LENGTH|MAGIC_LENGTH|N*sizeof(FLASH_write_t)|N*sizeof(FLASH_write_t) */ +/* | header 1 | header 2 |SWAP magic |CLEAN pat. | N*CPY_TO_ACTIVE_SLOT | N*CPY_TO_DWL_SLOT */ +/* */ +/* Please note that the size of the trailer area (N*CPY_TO_SLOTx) depends directly on SFU_LL_FLASH_write_t type, */ +/* so it can differ from one platform to another (this is FLASH-dependent) */ +#define TRAILER_SIZE(A) ((sizeof(SFU_LL_FLASH_write_t)*(TRAILER_INDEX(A)))\ + + (sizeof(SFU_LL_FLASH_write_t)*(TRAILER_INDEX(A))) + (uint32_t)(TRAILER_HEADER)) +#define TRAILER_BEGIN(A) (( uint8_t *)(SlotStartAdd[A]\ + + SLOT_SIZE(A) - TRAILER_SIZE(A))) +#define TRAILER_CPY_TO_DWL_SLOT(A,i) ((void*)((uint32_t)TRAILER_BEGIN(A)\ + + (sizeof(SFU_LL_FLASH_write_t)*(TRAILER_INDEX(A))) \ + + (uint32_t)TRAILER_HEADER+((i)*sizeof(SFU_LL_FLASH_write_t)))) +#define TRAILER_CPY_TO_ACTIVE_SLOT(A,i) ((void*)((uint32_t)TRAILER_BEGIN(A)\ + + (uint32_t)TRAILER_HEADER+((i)*sizeof(SFU_LL_FLASH_write_t)))) + +#define TRAILER_HDR_VALID(A) ((uint8_t *)(TRAILER_BEGIN(A))) +#define TRAILER_HDR_TEST(A) ((uint8_t *)(TRAILER_BEGIN(A) + SE_FW_HEADER_TOT_LEN)) +#define TRAILER_SWAP_ADDR(A) ((uint8_t *)(TRAILER_BEGIN(A) + SE_FW_HEADER_TOT_LEN + SE_FW_HEADER_TOT_LEN)) +#define TRAILER_CLEAN_ADDR(A)((uint8_t *)(TRAILER_BEGIN(A)\ + + SE_FW_HEADER_TOT_LEN + SE_FW_HEADER_TOT_LEN + MAGIC_LENGTH)) + +#define CHUNK_1_ADDR(A,B,C) ((uint8_t *)(SlotStartAdd[A]\ + +(SLOT_SIZE(SLOT_SWAP)*(B))+(SFU_IMG_CHUNK_SIZE*(C)))) +#define CHUNK_0_ADDR(A,B,C) ((uint8_t *)(SlotStartAdd[A]\ + +(SLOT_SIZE(SLOT_SWAP)*(B))+(SFU_IMG_CHUNK_SIZE*(C)))) + +#define CHUNK_0_ADDR_HEADER(A,B,C) ((((B)==0) && ((C)==0))?\ + (uint8_t *)(SlotHeaderAdd[(A)]) : \ + (uint8_t *)(SlotStartAdd[(A)]\ + +(SLOT_SIZE(SLOT_SWAP)*(B))+(SFU_IMG_CHUNK_SIZE*(C)))) + +#define CHUNK_0_ADDR_MODIFIED(A,B,C) ((((B)==0) && ((C)==0))?\ + ((uint8_t*)(SlotStartAdd[(A)] + SFU_IMG_IMAGE_OFFSET)) : \ + ((uint8_t*)(SlotStartAdd[(A)] + (SLOT_SIZE(SLOT_SWAP)*(B)) \ + + (SFU_IMG_CHUNK_SIZE*(C))))) +#define CHUNK_SWAP_ADDR(B) ((uint8_t *)(SlotStartAdd[SLOT_SWAP]+(SFU_IMG_CHUNK_SIZE*(B)))) + +/* Private variables ----------------------------------------------------------*/ +/* Trailer pattern : sizeof of write access type */ +static const int8_t SWAPPED[sizeof(SFU_LL_FLASH_write_t)] __attribute__((aligned(8))) = {0, 0, 0, 0, 0, 0, 0, 0}; +static const int8_t NOT_SWAPPED[sizeof(SFU_LL_FLASH_write_t)] __attribute__((aligned(8))) = {-1, -1, -1, -1, -1, -1, + -1, -1 + }; + +/* Functions Definition : helper ---------------------------------------------*/ +#if defined(ENABLE_IMAGE_STATE_HANDLING) +/** + * @brief Checks if a rollback is required + * @param SlotNumber index of the slot in the list + * @retval SFU_SUCCESS if Image should be rollbacked, a SFU_ERROR otherwise. + */ +static SFU_ErrorStatus FirmwareToRollback(uint32_t SlotNumber, SE_FwStateTypeDef MasterSlotState) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_ErrorStatus e_ret_status_se; + SE_FwStateTypeDef image_state = FWIMG_STATE_INVALID; + SE_StatusTypeDef e_se_status; + SE_FwStateTypeDef e_next_image_state; + + + /* If an image is detected, read the image state : + * if image is new, nothing to do. Switch from NEW to SELFTEST will be done before when launching user application. + * if image is selftest, set to invalid. Rollback required. + * if image is valid, nothing to do. + * if image is invalid, Rollback is required. + */ + if (SFU_SUCCESS == SFU_IMG_DetectFW(SlotNumber)) + { + e_ret_status_se = SE_SFU_IMG_GetActiveFwState(&e_se_status, SlotNumber, &image_state); + if (e_ret_status_se == SE_SUCCESS) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t SLOT_ACTIVE_%d state = %d", SlotNumber, image_state); +#endif /* (SFU_VERBOSE_DEBUG_MODE) */ + switch (image_state) + { + case FWIMG_STATE_NEW: + { + /* Multiple reset can occur during installation + * Switch from NEW to SELFTEST will be done before when launching user application + */ + break; + } + case FWIMG_STATE_SELFTEST: + { + if (MasterSlotState == FWIMG_STATE_VALID_ALL) + { + /* Master slot is in VALID_ALL state, all other images should be validated + * Compare to successive validation operations VALID_ALL is a single request thus robust to reset + */ + e_next_image_state = FWIMG_STATE_VALID; + e_ret_status_se = SE_SFU_IMG_SetActiveFwState(&e_se_status, SlotNumber, &e_next_image_state); +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status_se != SE_SUCCESS) + { + TRACE("\r\n\t SLOT_ACTIVE_%d state update error", SlotNumber); + } +#endif /* (SFU_VERBOSE_DEBUG_MODE) */ + e_ret_status = SFU_ERROR; + } + else + { + /* Bootloader should never find an image in SELFTEST state - bootloader + * assumes self test was not able to complete and marks image as INVALID + */ + e_next_image_state = FWIMG_STATE_INVALID; + e_ret_status_se = SE_SFU_IMG_SetActiveFwState(&e_se_status, SlotNumber, &e_next_image_state); +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status_se != SE_SUCCESS) + { + TRACE("\r\n\t SLOT_ACTIVE_%d state update error", SlotNumber); + } +#endif /* (SFU_VERBOSE_DEBUG_MODE) */ + e_ret_status = SFU_SUCCESS; + } + break; + } + case FWIMG_STATE_VALID: + case FWIMG_STATE_VALID_ALL: + { + break; + } + default: + { + /* image may be in INVALID state + * Image marked as invalid failed selftest so we need to attempt a rollback to last good image + */ + e_ret_status = SFU_SUCCESS; + break; + } + } + } + } + return e_ret_status; +} + +/** + * @brief Updates the finger print of the new firmware the header signature of the previous firmware + * @param pNewHeader: pointer in ram to header of new installed fw + * @param pPrevHeader: pointer in ram to header of backed-up fw + * @retval none + */ +static void UpdateHeaderFingerPrint(SE_FwRawHeaderTypeDef *pNewHeader, SE_FwRawHeaderTypeDef *pPrevHeader) +{ + (void) memcpy(pNewHeader->PrevHeaderFingerprint, pPrevHeader->HeaderSignature, + sizeof(pNewHeader->PrevHeaderFingerprint)); +} +#endif /* (ENABLE_IMAGE_STATE_HANDLING) */ + +/** + * @brief Check the magic from trailer or counter + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus CheckTrailerMagic(uint32_t DwlSlot) +{ + uint8_t magic[MAGIC_LENGTH]; + uint8_t clean[MAGIC_LENGTH]; + uint8_t signature_valid[MAGIC_LENGTH / 2]; + uint8_t signature_test[MAGIC_LENGTH / 2]; + uint8_t erased_flash_pattern[MAGIC_LENGTH]; + + /* Pattern initialization */ + (void) memset(erased_flash_pattern, 0xFF, MAGIC_LENGTH); + + /* Read trailer fields : TRAILER_HDR_VALID, TRAILER_HDR_TEST, MAGIC, CLEAN */ + if (SFU_LL_FLASH_Read(signature_valid, + (uint8_t *)((uint32_t)TRAILER_HDR_VALID(DwlSlot) + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), + sizeof(signature_valid)) != SFU_SUCCESS) + { + return SFU_ERROR; + } + if (SFU_LL_FLASH_Read(signature_test, + (uint8_t *)((uint32_t) TRAILER_HDR_TEST(DwlSlot) + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), + sizeof(signature_test)) != SFU_SUCCESS) + { + return SFU_ERROR; + } + if (SFU_LL_FLASH_Read(magic, TRAILER_SWAP_ADDR(DwlSlot), MAGIC_LENGTH) != SFU_SUCCESS) + { + return SFU_ERROR; + } + if (SFU_LL_FLASH_Read(clean, TRAILER_CLEAN_ADDR(DwlSlot), MAGIC_LENGTH) != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* + * Check magic validity : + * - last 16 bytes of validated header + * - last 16 bytes of test header + * - significant values (not an erased flash pattern) + * + * Check clean tag not set : + * - should be erased flash pattern but not clean-up paatern (0x55 0x55 ...) + */ + if ((memcmp(magic, signature_valid, sizeof(signature_valid)) != 0) + || (memcmp(&magic[MAGIC_LENGTH / 2U], signature_test, sizeof(signature_test)) != 0) + || (memcmp(magic, erased_flash_pattern, MAGIC_LENGTH) == 0) + || (memcmp(clean, erased_flash_pattern, MAGIC_LENGTH) != 0)) + { + return SFU_ERROR; + } + return SFU_SUCCESS; +} + +/** + * @brief Write the minimum value possible on the flash + * @param pAddr: pointer to address to write . + * @param pValue: pointer to the value to write + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + * + * @note This function should be FLASH dependent. + * We abstract this dependency thanks to the type SFU_LL_FLASH_write_t. + * See @ref SFU_LL_FLASH_write_t + */ +static SFU_ErrorStatus AtomicWrite(uint8_t *pAddr, SFU_LL_FLASH_write_t *pValue) +{ + SFU_FLASH_StatusTypeDef flash_if_info; + + return SFU_LL_FLASH_Write(&flash_if_info, pAddr, (uint8_t *)pValue, sizeof(SFU_LL_FLASH_write_t)); +} + +/** + * @brief Clean Magic value + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus CleanMagicValue(uint32_t DwlSlot) +{ + SFU_FLASH_StatusTypeDef flash_if_info; + uint8_t clean_tag[MAGIC_LENGTH]; + + /* set the clean tag into trailer */ + (void) memset(clean_tag, 0x55, MAGIC_LENGTH); + return SFU_LL_FLASH_Write(&flash_if_info, TRAILER_CLEAN_ADDR(DwlSlot), clean_tag, MAGIC_LENGTH); +} + +/** + * @brief Write Trailer Headers : TEST + VALID + SWAP + * @param DwlSlot identification of the downloaded area + * @param pValidHeader: pointer in ram to header of valid fw to backup + * @param pTestHeader: pointer in ram to header of fw to test + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus WriteTrailerHeader(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pValidHeader, + SE_FwRawHeaderTypeDef *pTestHeader) +{ + /* everything is in place , just compute from present data and write it */ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_info; + uint8_t magic[MAGIC_LENGTH]; + uint32_t buffer; + + /* Write Headers VALID + TEST */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, TRAILER_HDR_TEST(DwlSlot), (uint8_t *) pTestHeader, + SE_FW_HEADER_TOT_LEN); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, TRAILER_HDR_VALID(DwlSlot), (uint8_t *) pValidHeader, + SE_FW_HEADER_TOT_LEN); + } + + /* Write Magic */ + if (e_ret_status == SFU_SUCCESS) + { + buffer = (uint32_t) pValidHeader; + (void) memcpy(&magic[0U], (uint8_t *)(buffer + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), MAGIC_LENGTH / 2U); + buffer = (uint32_t) pTestHeader; + (void) memcpy(&magic[MAGIC_LENGTH / 2U], (uint8_t *)(buffer + SE_FW_AUTH_LEN + (MAGIC_LENGTH / 2U)), + MAGIC_LENGTH / 2U); + e_ret_status = SFU_LL_FLASH_Write(&flash_if_info, TRAILER_SWAP_ADDR(DwlSlot), magic, MAGIC_LENGTH); + } + + return e_ret_status; +} + +/** + * @brief Erase the size of the swap area in a given slot sector. + * @note The erasure occurs at @: @slot + index*swap_area_size + * @param SlotNumber index of the slot in the list + * @param Index This is the number of "swap size" we jump from the slot start + * @retval SFU_ SUCCESS if valid, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus EraseSlotIndex(uint32_t SlotNumber, uint32_t index) +{ + SFU_FLASH_StatusTypeDef flash_if_status; + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t buffer; + + buffer = SlotStartAdd[SlotNumber]; + buffer = buffer + (SLOT_SIZE(SLOT_SWAP) * index); + + /* If this is an active slot and the index is 0 then header is concerned */ + if ((SlotNumber >= SLOT_ACTIVE_1) && (SlotNumber <= (SLOT_ACTIVE_1 + SFU_NB_MAX_ACTIVE_IMAGE)) && (index == 0U)) + { + + /* + * As the header may not be contiguous with FW, this action is split in 2 actions : + * - HEADER : executed in secured environment + * - remaining part : done by SBSFU + */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotHeaderAdd[SlotNumber], + SFU_IMG_IMAGE_OFFSET) ; + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotStartAdd[SlotNumber] + + SFU_IMG_IMAGE_OFFSET, SLOT_SIZE(SLOT_SWAP) - SFU_IMG_IMAGE_OFFSET); + } + } + else + { + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *)buffer, SLOT_SIZE(SLOT_SWAP)) ; + } + + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED) + return e_ret_status; +} + +/** + * @brief Verify image signature of binary after decryption + * @param DwlSlot identification of the downloaded area + * @param pSeStatus pointer giving the SE status result + * @param pFwImageHeader pointer to fw header + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus VerifyFwSignatureAfterDecrypt(SE_StatusTypeDef *pSeStatus, uint32_t DwlSlot, + SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SE_Ex_PayloadDescTypeDef payload_desc; + uint32_t fw_size; + uint32_t fw_offset; + + /* + * The values below are not necessarily matching the way the firmware + * has been spread in FLASH but this is adjusted later on in the this function. + */ + payload_desc.pPayload[0] = SlotStartAdd[SLOT_SWAP]; + payload_desc.PayloadSize[0] = SLOT_SIZE(SLOT_SWAP); + payload_desc.pPayload[1] = SlotStartAdd[DwlSlot]; + payload_desc.PayloadSize[1] = SLOT_SIZE(DwlSlot); + + fw_size = pFwImageHeader->PartialFwSize; + fw_offset = (SFU_IMG_IMAGE_OFFSET + (pFwImageHeader->PartialFwOffset % SLOT_SIZE(SLOT_SWAP))) % + SLOT_SIZE(SLOT_SWAP); + + /* + * Adjusting the description of the way the Firmware is written in FLASH. + */ + payload_desc.pPayload[0] = payload_desc.pPayload[0] + fw_offset; + + /* The first part contains the execution offset so the payload size must be adjusted accordingly */ + payload_desc.PayloadSize[0] = payload_desc.PayloadSize[0] - fw_offset; + + if (fw_size <= payload_desc.PayloadSize[0]) + { + /* The firmware is written fully in a contiguous manner */ + payload_desc.PayloadSize[0] = fw_size; + payload_desc.PayloadSize[1] = 0U; + payload_desc.pPayload[1] = 0U; + } + else + { + /* + * The firmware is too big to be contained in the first payload slot. + * So, the firmware is split in 2 non-contiguous parts + */ + + if ((payload_desc.pPayload[1] == 0U) + || (payload_desc.PayloadSize[1] < (fw_size - payload_desc.PayloadSize[0]))) + { + return SFU_ERROR; + } + + /* The second part contains the end of the firmware so the size is the total size - size already stored in the + first area */ + payload_desc.PayloadSize[1] = fw_size - payload_desc.PayloadSize[0]; + + } + + /* Signature Verification */ + return VerifyFwSignatureScatter(pSeStatus, DwlSlot, pFwImageHeader, &payload_desc, SE_FW_IMAGE_PARTIAL); +} + + +/** + * @brief Swap active slot with decrypted FW to install + * With the 2 images implementation, installing a new Firmware Image means swapping active slot and dwl slot. + * To perform this swap, the image to be installed is split in blocks of the swap size: + * SLOT_SIZE(DwlSlot) / SLOT_SIZE(SLOT_SWAP) blocks to be swapped . + * Each of these blocks is swapped using smaller chunks of SFU_IMG_CHUNK_SIZE size. + * The swap starts from the tail of the image and ends with the beginning of the image ("swap from tail to + * head"). + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer in ram to the header to install + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus SwapFirmwareImages(uint32_t ActiveSlot, uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_status; + SFU_LL_FLASH_write_t trailer; + int32_t index_active_slot; + int32_t index_dwl_slot_write; + int32_t index_dwl_slot_read; + int32_t chunk; + uint8_t buffer[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + int32_t index_active_slot_partial_begin; + int32_t index_active_slot_partial_end; + int32_t index_active_slot_final_end; + int32_t index_dwl_slot_partial_end; + int32_t index_active_slot_empty_begin; + /* number_of_index_active_slot is the number of blocks in active slot (block of SLOT_SIZE(SLOT_SWAP) bytes) */ + uint32_t number_of_index_active_slot = SLOT_SIZE(ActiveSlot) / SLOT_SIZE(SLOT_SWAP); + /* number_of_index_dwl_slot is the number of blocks in dwl slot (block of SLOT_SIZE(SLOT_SWAP) bytes) */ + uint32_t number_of_index_dwl_slot = SLOT_SIZE(DwlSlot) / SLOT_SIZE(SLOT_SWAP); + /* number_of_chunk is the number of chunks used to swap 1 block (moving a block of SLOT_SIZE(SLOT_SWAP) bytes + split in number_of_chunk chunks of SFU_IMG_CHUNK_SIZE bytes) */ + uint32_t number_of_chunk = SLOT_SIZE(SLOT_SWAP) / SFU_IMG_CHUNK_SIZE; + uint32_t write_len; + uint32_t offset_block_partial_begin; + uint32_t offset_block_partial_end; + uint32_t offset_block_final_end; + + TRACE("\r\n\t Image preparation done.\r\n\t Swapping the firmware images"); + + /* index_active_slot_partial_begin is the index of first block (of SLOT_SIZE(SLOT_SWAP) bytes) in active slot + impacted by partial image */ + index_active_slot_partial_begin = (SFU_IMG_IMAGE_OFFSET + pFwImageHeader->PartialFwOffset) / + SLOT_SIZE(SLOT_SWAP); + + /* offset_block_partial_begin is the offset of first byte of partial image inside index_active_slot_partial_begin + block */ + offset_block_partial_begin = (SFU_IMG_IMAGE_OFFSET + pFwImageHeader->PartialFwOffset) % + SLOT_SIZE(SLOT_SWAP); + + /* In case of COMPLETE update, the full slots are swapped + Assumption : DwlSlot is at least greater than ActiveSlot */ + if ((pFwImageHeader->FwSize == pFwImageHeader->PartialFwSize) && (SLOT_SIZE(DwlSlot) >= SLOT_SIZE(ActiveSlot))) + { + /* index_active_slot_partial_end is the index of block (of SLOT_SIZE(SLOT_SWAP) bytes) of first byte following + partial image in active slot */ + index_active_slot_partial_end = (SLOT_SIZE(ActiveSlot) - TRAILER_SIZE(DwlSlot)) / SLOT_SIZE(SLOT_SWAP); + + /* offset_block_partial_end is the offset of first byte following partial image, inside + index_active_slot_partial_end block */ + offset_block_partial_end = (SLOT_SIZE(ActiveSlot) - TRAILER_SIZE(DwlSlot)) % SLOT_SIZE(SLOT_SWAP); + + /* index_dwl_slot_partial_end is the index of block (of SLOT_SIZE(SLOT_SWAP) bytes) of first byte following + partial image in dwl slot or swap area */ + index_dwl_slot_partial_end = ((SLOT_SIZE(ActiveSlot) - TRAILER_SIZE(DwlSlot)) / SLOT_SIZE(SLOT_SWAP)) - 1U; + + /* index_active_slot_final_end is the index of block (of SLOT_SIZE(SLOT_SWAP) bytes) of first byte following final + image in active slot */ + index_active_slot_final_end = (SLOT_SIZE(ActiveSlot) - TRAILER_SIZE(DwlSlot)) / SLOT_SIZE(SLOT_SWAP); + + /* offset_block_final_end is the offset of first byte following final image, inside index_active_slot_final_end + block */ + offset_block_final_end = (SLOT_SIZE(ActiveSlot) - TRAILER_SIZE(DwlSlot)) % SLOT_SIZE(SLOT_SWAP); + + /* set index_dwl_slot_write: starting from the end */ + index_dwl_slot_write = (SLOT_SIZE(ActiveSlot) - TRAILER_SIZE(DwlSlot)) / SLOT_SIZE(SLOT_SWAP); + + } + else + { + /* index_active_slot_partial_end is the index of block (of SLOT_SIZE(SLOT_SWAP) bytes) of first byte following + partial image in active slot */ + index_active_slot_partial_end = (SFU_IMG_IMAGE_OFFSET + pFwImageHeader->PartialFwOffset + + pFwImageHeader->PartialFwSize) / SLOT_SIZE(SLOT_SWAP); + + /* offset_block_partial_end is the offset of first byte following partial image, inside + index_active_slot_partial_end block */ + offset_block_partial_end = (SFU_IMG_IMAGE_OFFSET + pFwImageHeader->PartialFwOffset + + pFwImageHeader->PartialFwSize) % SLOT_SIZE(SLOT_SWAP); + + /* index_dwl_slot_partial_end is the index of block (of SLOT_SIZE(SLOT_SWAP) bytes) of first byte following + partial image in dwl slot or swap area */ + index_dwl_slot_partial_end = (((SFU_IMG_IMAGE_OFFSET + (pFwImageHeader->PartialFwOffset % + SLOT_SIZE(SLOT_SWAP))) % SLOT_SIZE(SLOT_SWAP) + + pFwImageHeader->PartialFwSize) / SLOT_SIZE(SLOT_SWAP)) - 1U; + + /* index_active_slot_final_end is the index of block (of SLOT_SIZE(SLOT_SWAP) bytes) of first byte following + final image in active slot */ + index_active_slot_final_end = ((SFU_IMG_IMAGE_OFFSET + pFwImageHeader->FwSize) / SLOT_SIZE(SLOT_SWAP)); + + /* offset_block_final_end is the offset of first byte following final image, inside index_active_slot_final_end + block */ + offset_block_final_end = (SFU_IMG_IMAGE_OFFSET + pFwImageHeader->FwSize) % SLOT_SIZE(SLOT_SWAP); + + /* set index_dwl_slot_write: starting from the end, block index in dwl slot or swap area to receive block from + active slot */ + if (index_active_slot_partial_end == (number_of_index_active_slot - 1)) + { + /* last block of dwl slot can only receive last block of active slot, due to trailer presence */ + index_dwl_slot_write = number_of_index_dwl_slot - 1; + } + else + { + index_dwl_slot_write = number_of_index_dwl_slot - 2; + } + } + + /* set index_active_slot: starting from the end, block index from active slot to copy in dwl slot */ + index_active_slot = index_active_slot_partial_end; + + /* set index_dwl_slot_read: starting from the end, block index in dwl slot or swap area to copy updated image to + active slot */ + index_dwl_slot_read = index_dwl_slot_partial_end; + + /* Adjust indexes in case offset is 0: in this case, first block to swap is the previous one */ + if (offset_block_partial_end == 0) + { + index_active_slot--; + index_dwl_slot_read--; + } + + /* + * dwl slot read index should be lower than dwl slot write index. + * If not the case, the dwl slot is not big enough to manage this partial firmware image + * (depends on offset and size). + */ + if (index_dwl_slot_read >= index_dwl_slot_write) + { + return SFU_ERROR; + } + + /* Swap one block at each loop, until all targeted blocks of active slot have been copied + * Concerned blocks are: + * 1- block impacted by partial image + * 2- first block containing the header + */ + while (index_active_slot >= 0) + { + /* Reload watchdoag every SWAP size */ + SFU_LL_SECU_IWDG_Refresh(); + + TRACE("."); + + if ((index_dwl_slot_write < -1) || (index_dwl_slot_read < -1)) + { + return SFU_ERROR; + } + + /* If CPY_TO_DWL_SLOT(i) is still virgin, then swap the block from active slot to dwl slot */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &trailer, + TRAILER_CPY_TO_DWL_SLOT(DwlSlot, TRAILER_INDEX(DwlSlot) - 1 - index_active_slot), + sizeof(trailer)); + if ((e_ret_status == SFU_SUCCESS) && (memcmp(&trailer, NOT_SWAPPED, sizeof(trailer)) == 0)) + { + /* Erase destination block in dwl slot or swap, if not the trailer block */ + if (index_dwl_slot_write != (number_of_index_dwl_slot - 1)) + { + if (index_dwl_slot_write == -1) + { + /* Erase the swap */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotStartAdd[SLOT_SWAP], + SLOT_SIZE(SLOT_SWAP)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED) + } + else /* index_dwl_slot_write >= 0 */ + { + /* erase the size of "swap area" at @: Dwl slot + index_dwl_slot_write*swap_area_size */ + e_ret_status = EraseSlotIndex(DwlSlot, index_dwl_slot_write); + } + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + + /* Copy the block from active slot to dwl slot or swap (using "number_of_chunk" chunks) */ + for (chunk = (number_of_chunk - 1); chunk >= 0 ; chunk--) + { + /* ignore return value, no double ecc error is expected, area already read before */ + (void)SFU_LL_FLASH_Read(buffer, CHUNK_0_ADDR_HEADER(ActiveSlot, index_active_slot, chunk), sizeof(buffer)); + write_len = sizeof(buffer); + if (index_dwl_slot_write == -1) + { + /* Destination block is the swap */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, CHUNK_SWAP_ADDR(chunk), buffer, write_len); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + else /* index_dwl_slot_write >= 0 */ + { + /* Destination block is in dwl slot: Do not overwrite the trailer. */ + if (((uint32_t)CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk)) < (uint32_t)TRAILER_BEGIN(DwlSlot)) + { + /* write is possible length can be modified */ + if ((uint32_t)(CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk) + write_len) > + (uint32_t)TRAILER_BEGIN(DwlSlot)) + { + write_len = TRAILER_BEGIN(DwlSlot) - CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk); + } + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk), + buffer, write_len); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + } + } + + /* + * The block of the active firmware has been backed up. + * The trailer is updated to memorize this: the CPY bytes at the appropriate index are set to SWAPPED. + */ + e_ret_status = AtomicWrite(TRAILER_CPY_TO_DWL_SLOT(DwlSlot, (TRAILER_INDEX(DwlSlot) - 1 - index_active_slot)), + (SFU_LL_FLASH_write_t *) SWAPPED); + + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + + /* If CPY_TO_ACTIVE_SLOT(i) is still virgin, then swap the block from dwl slot to active slot */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &trailer, + TRAILER_CPY_TO_ACTIVE_SLOT(DwlSlot, TRAILER_INDEX(DwlSlot) - 1 - + index_active_slot), + sizeof(trailer)); + if ((e_ret_status == SFU_SUCCESS) && (memcmp(&trailer, NOT_SWAPPED, sizeof(trailer)) == 0)) + { + /* erase the size of "swap area" at @: active slot + index_active_slot*swap_area_size*/ + e_ret_status = EraseSlotIndex(ActiveSlot, index_active_slot); + + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* + * Fill block in active slot: + * The appropriate update image block of dwl slot together with initial image block that has been backed up in + * dwl slot, + * are associated to constitute final block in active slot (installing the block of the new firmware image). + */ + for (chunk = (number_of_chunk - 1); chunk >= 0 ; chunk--) + { + /* Read complete chunk of updated image */ + if (index_dwl_slot_read == -1) + { + /* ignore return value, no double ecc error is expected, area already read before */ + (void)SFU_LL_FLASH_Read(buffer, CHUNK_SWAP_ADDR(chunk), sizeof(buffer)); + } + else /* index_dwl_slot_read >= 0 */ + { + /* ignore return value, no double ecc error is expected, area already read before */ + (void)SFU_LL_FLASH_Read(buffer, CHUNK_1_ADDR(DwlSlot, index_dwl_slot_read, chunk), sizeof(buffer)); + } + + /* Last impacted block: end of block has to be updated with initial image */ + if (index_active_slot == index_active_slot_partial_end) + { + /* If chunk is not impacted by updated image, chunk fully takes initial image content */ + if (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk) >= (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, + 0) + offset_block_partial_end)) + { + /* check return value, as this area has not been read before */ + e_ret_status = SFU_LL_FLASH_Read(buffer, CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk), + sizeof(buffer)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + + /* If chunk is partially impacted by updated image, end of chunk is updated with the initial image content */ + if ((CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk) < (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, + 0) + offset_block_partial_end)) + && ((CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, (chunk + 1))) > + (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, 0) + offset_block_partial_end))) + { + /* check return value, as this area has not been read before */ + e_ret_status = SFU_LL_FLASH_Read(buffer + (offset_block_partial_end % SFU_IMG_CHUNK_SIZE), + CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk) + + (offset_block_partial_end % SFU_IMG_CHUNK_SIZE), + sizeof(buffer) - (offset_block_partial_end % SFU_IMG_CHUNK_SIZE)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + } + + /* First impacted block: beginning of block has to be updated with initial image */ + if (index_active_slot == index_active_slot_partial_begin) + { + /* If chunk is not impacted by updated image, chunk fully takes initial image content */ + if (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, (chunk + 1)) <= + (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, 0) + offset_block_partial_begin)) + { + /* check return value, as this area has not been read before */ + e_ret_status = SFU_LL_FLASH_Read(buffer, CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk), + sizeof(buffer)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + + /* If chunk is partially impacted by updated image, beginning of chunk is updated with the initial image + content */ + if ((CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk) < + (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, 0) + offset_block_partial_begin)) && + (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, (chunk + 1)) > + (CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, 0) + offset_block_partial_begin))) + { + /* check return value, as this area has not been read before */ + e_ret_status = SFU_LL_FLASH_Read(buffer, CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk), + offset_block_partial_begin % SFU_IMG_CHUNK_SIZE); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + } + /* Header block not impacted by partial image: complete block, except header, is updated with initial image */ + else if (index_active_slot == 0) + { + /* check return value, as this area has not been read before */ + e_ret_status = SFU_LL_FLASH_Read(buffer, CHUNK_1_ADDR(DwlSlot, index_dwl_slot_write, chunk), sizeof(buffer)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + + /* Last block of final image: end of block has to be cleaned with empty data */ + if (index_active_slot == index_active_slot_final_end) + { + /* If chunk is completely beyond the final image, then chunk takes empty data */ + if (CHUNK_0_ADDR(ActiveSlot, index_active_slot, chunk) >= + CHUNK_0_ADDR(ActiveSlot, index_active_slot_final_end, 0) + offset_block_final_end) + { + memset(buffer, 0xFF, sizeof(buffer)); + } + + /* If chunk is partially beyond the final image, then chunk is partially updated with empty data */ + if ((CHUNK_0_ADDR(ActiveSlot, index_active_slot, chunk) < + (CHUNK_0_ADDR(ActiveSlot, index_active_slot_final_end, 0) + offset_block_final_end)) && + (CHUNK_0_ADDR(ActiveSlot, index_active_slot, (chunk + 1)) > + (CHUNK_0_ADDR(ActiveSlot, index_active_slot_final_end, 0) + offset_block_final_end))) + { + memset(buffer + (offset_block_final_end % SFU_IMG_CHUNK_SIZE), 0xFF, + sizeof(buffer) - (offset_block_final_end % SFU_IMG_CHUNK_SIZE)); + } + } + + write_len = SFU_IMG_CHUNK_SIZE; + /* don't copy header in active slot + this will be done at the end during validation step */ + if ((index_active_slot == 0) && (chunk == 0)) + { + write_len = write_len - SFU_IMG_IMAGE_OFFSET; + } + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, CHUNK_0_ADDR_MODIFIED(ActiveSlot, index_active_slot, chunk), + buffer, write_len); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + + /* + * The block of the active firmware has been backed up. + * The trailer is updated to memorize this: the CPY bytes at the appropriate index are set to SWAPPED. + * Except for block 0, because block 0 is incomplete at this stage (final header installation not yet done) + */ + if (index_active_slot != 0) + { + e_ret_status = AtomicWrite(TRAILER_CPY_TO_ACTIVE_SLOT(DwlSlot, + (TRAILER_INDEX(DwlSlot) - 1 - index_active_slot)), + (SFU_LL_FLASH_write_t *) SWAPPED); + + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + } + } + + /* Decrement all block indexes */ + index_dwl_slot_write--; + index_dwl_slot_read--; + index_active_slot--; + + /* + * After having copied the impacted image blocks from active slot, copy also the first block + * due to header, if not already copied among the impacted image blocks. + */ + if ((index_active_slot < index_active_slot_partial_begin) && (index_active_slot >= 0)) + { + index_active_slot = 0; + index_dwl_slot_read = -1; /* force read from swap area, to avoid exiting dwl slot / swap index allowed range */ + } + } + + /* + * Now, erase the blocks in active slot, located after final image + */ + if (offset_block_final_end == 0) + { + index_active_slot_empty_begin = index_active_slot_final_end; + } + else + { + index_active_slot_empty_begin = index_active_slot_final_end + 1; + } + index_active_slot = number_of_index_active_slot - 1; + while (index_active_slot >= index_active_slot_empty_begin) + { + e_ret_status = EraseSlotIndex(ActiveSlot, index_active_slot); + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* Decrement block index */ + index_active_slot--; + } + + return e_ret_status; +} + +#ifdef ENABLE_IMAGE_STATE_HANDLING +/** + * @brief Executes a rollback to the original firmware if a firmware update fails + * @param ActiveSlot identification of the new active image + * @param DwlSlot identification of previous firmware image (backed-up slot) + * @param pFwImageHeader pointer in ram to the header of the backed-up FW + * @retval SFU_ErrorStatus SFU_SUCCESS if the rollback is successful, error code otherwise + */ +static SFU_ErrorStatus RollbackInstallation(uint32_t ActiveSlot, uint32_t DwlSlot, + SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t number_chunk_per_sector = SLOT_SIZE(SLOT_SWAP) / SFU_IMG_CHUNK_SIZE; + SFU_FLASH_StatusTypeDef flash_if_status; + uint8_t buffer[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + SE_FwRawHeaderTypeDef *p_header; + uint32_t size; + uint32_t pass_index; + uint32_t erase_index; + uint32_t fw_source_address; + uint32_t fw_dest_write_address; + uint32_t fw_dest_erase_address; + + if (number_chunk_per_sector == 0U) + { + return SFU_ERROR; + } + + size = pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET; + fw_source_address = SlotStartAdd[DwlSlot] + (((size - 1U) / SFU_IMG_CHUNK_SIZE) * SFU_IMG_CHUNK_SIZE); + fw_dest_write_address = SlotStartAdd[ActiveSlot] + (((size - 1U) / SFU_IMG_CHUNK_SIZE) * SFU_IMG_CHUNK_SIZE); + fw_dest_erase_address = SlotStartAdd[ActiveSlot] + (((size - 1U) / SLOT_SIZE(SLOT_SWAP)) * SLOT_SIZE(SLOT_SWAP)); + pass_index = ((size - 1U) / SFU_IMG_CHUNK_SIZE) + 1U; + erase_index = (pass_index - 1U) / number_chunk_per_sector * number_chunk_per_sector; + + /* Erase the part of the active slot that will not be updated + ========================================================== */ + size = (SLOT_SIZE(ActiveSlot) - (pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET)) / SLOT_SIZE(SLOT_SWAP) * + SLOT_SIZE(SLOT_SWAP); + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *)(fw_dest_erase_address + SLOT_SIZE(SLOT_SWAP)), + size); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + while ((e_ret_status == SFU_SUCCESS) && (pass_index > 0U)) + { + /* Reading phase + =============== */ + e_ret_status = SFU_LL_FLASH_Read(buffer, (uint8_t *) fw_source_address, SFU_IMG_CHUNK_SIZE); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + + /* Erasing operation when aligned on erase_index + ============================================= */ + + /* + * The header may not be contiguous with the FW image : 2 erasing operations needed + */ + if (e_ret_status == SFU_SUCCESS) + { + if ((((pass_index - 1U) / number_chunk_per_sector) * number_chunk_per_sector) == erase_index) + { + (void) SFU_LL_SECU_IWDG_Refresh(); + size = 0U; + if (erase_index == 0U) + { + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotHeaderAdd[ActiveSlot], + SFU_IMG_IMAGE_OFFSET); + size = SFU_IMG_IMAGE_OFFSET; + } + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) fw_dest_erase_address + size, + SLOT_SIZE(SLOT_SWAP) - size); + } + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + erase_index -= number_chunk_per_sector; + fw_dest_erase_address -= SLOT_SIZE(SLOT_SWAP); + } + } + + /* Writing phase + ============= */ + /* + * Header is under isolated environment protection + * Thus the writing operation is split in 2 actions (HEADER + remaining part) + */ + if (e_ret_status == SFU_SUCCESS) + { + size = 0U; + if (pass_index == 1U) + { + /* Ensure there is no Fingerprint in original firmware header + * This stops someone attempting multiple rollbacks by writing fake fingerprint in original header + */ + p_header = (SE_FwRawHeaderTypeDef *) buffer; + (void) memset(p_header->PrevHeaderFingerprint, 0x00, sizeof(p_header->PrevHeaderFingerprint)); + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *) SlotHeaderAdd[ActiveSlot], buffer, + SFU_IMG_IMAGE_OFFSET); + size = SFU_IMG_IMAGE_OFFSET; + } + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *) fw_dest_write_address + size, buffer + size, + SFU_IMG_CHUNK_SIZE - size); + } + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + } + + /* Index update + ============ */ + pass_index--; + fw_source_address -= SFU_IMG_CHUNK_SIZE; + fw_dest_write_address -= SFU_IMG_CHUNK_SIZE; + } + + return e_ret_status; +} +#endif /* ENABLE_IMAGE_STATE_HANDLING */ + + +/** + * @brief Decrypt Image in dwl slot + * @ note Decrypt is done from dwl slot to dwl slot + swap with 2 images (swap contains 1st sector) + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer in ram to the header to decrypt + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus DecryptImageInDwlSlot(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + SE_ErrorStatus se_ret_status; + uint32_t NumberOfChunkPerSwap = SLOT_SIZE(SLOT_SWAP) / SFU_IMG_CHUNK_SIZE; + SFU_FLASH_StatusTypeDef flash_if_status; + /* chunk size is the maximum , the 1st block can be smaller */ + /* the chunk is static to avoid large stack */ + uint8_t fw_decrypted_chunk[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + uint8_t fw_encrypted_chunk[SFU_IMG_CHUNK_SIZE] __attribute__((aligned(8))); + uint32_t fw_source_address = 0U; + uint32_t fw_dest_address_write = 0U; + uint32_t fw_dest_erase_address = 0U; + uint32_t fw_decrypted_total_size = 0U; + uint32_t size; + uint32_t oldsize; + uint32_t fw_decrypted_chunk_size; + uint32_t fw_tag_len; + uint8_t fw_tag_output[SE_TAG_LEN]; + uint32_t pass_index = 0U; + uint32_t erase_index = 0U; + + if ((pFwImageHeader == NULL)) + { + return e_ret_status; + } + + /* Decryption process*/ + se_ret_status = SE_Decrypt_Init(&e_se_status, pFwImageHeader, SE_FW_IMAGE_PARTIAL); + if ((se_ret_status == SE_SUCCESS) && (e_se_status == SE_OK)) + { + e_ret_status = SFU_SUCCESS; + + /* Decryption loop*/ + while ((e_ret_status == SFU_SUCCESS) && (fw_decrypted_total_size < (pFwImageHeader->PartialFwSize)) && + (e_se_status == SE_OK)) + { + if (pass_index == NumberOfChunkPerSwap) + { + fw_dest_address_write = SlotStartAdd[DwlSlot]; + fw_dest_erase_address = fw_dest_address_write; + erase_index = NumberOfChunkPerSwap; + } + if (pass_index == 0U) + { + fw_source_address = SlotStartAdd[DwlSlot] + SFU_IMG_IMAGE_OFFSET + + (pFwImageHeader->PartialFwOffset % SLOT_SIZE(SLOT_SWAP)); + fw_dest_erase_address = SlotStartAdd[SLOT_SWAP]; + fw_dest_address_write = fw_dest_erase_address + ((SFU_IMG_IMAGE_OFFSET + (pFwImageHeader->PartialFwOffset % + SLOT_SIZE(SLOT_SWAP))) % + SLOT_SIZE(SLOT_SWAP)); + fw_decrypted_chunk_size = sizeof(fw_decrypted_chunk) - + ((SFU_IMG_IMAGE_OFFSET + (pFwImageHeader->PartialFwOffset % SLOT_SIZE(SLOT_SWAP))) % + sizeof(fw_decrypted_chunk)); + if (fw_decrypted_chunk_size > pFwImageHeader->PartialFwSize) + { + fw_decrypted_chunk_size = pFwImageHeader->PartialFwSize; + } + pass_index = (((SFU_IMG_IMAGE_OFFSET + (pFwImageHeader->PartialFwOffset % SLOT_SIZE(SLOT_SWAP))) + % SLOT_SIZE(SLOT_SWAP)) / sizeof(fw_decrypted_chunk)); + } + else + { + fw_decrypted_chunk_size = sizeof(fw_decrypted_chunk); + + /* For the last 2 pass, divide by 2 remaining buffer to ensure that : + * - chunk size greater than 16 bytes : minimum size of a block to be decrypted + * - except last one chunk size is 16 bytes aligned + * + * Pass n - 1 : remaining bytes / 2 with (16 bytes alignment for crypto AND sizeof(SFU_LL_FLASH_write_t) for + * flash programming) + * Pass n : remaining bytes + */ + + /* Last pass : n */ + if ((pFwImageHeader->PartialFwSize - fw_decrypted_total_size) < fw_decrypted_chunk_size) + { + fw_decrypted_chunk_size = pFwImageHeader->PartialFwSize - fw_decrypted_total_size; + } + /* Previous pass : n - 1 */ + else if ((pFwImageHeader->PartialFwSize - fw_decrypted_total_size) < ((2U * fw_decrypted_chunk_size) - 16U)) + { + fw_decrypted_chunk_size = ((pFwImageHeader->PartialFwSize - fw_decrypted_total_size) / 32U) * 16U; + + /* Set dimension to the appropriate length for FLASH programming. + * Example: 64-bit length for L4. + */ + if ((fw_decrypted_chunk_size & ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - 1U)) != 0U) + { + fw_decrypted_chunk_size = fw_decrypted_chunk_size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - + (fw_decrypted_chunk_size % + (uint32_t)sizeof(SFU_LL_FLASH_write_t))); + } + } + /* All others pass */ + else + { + /* nothing */ + } + } + + size = fw_decrypted_chunk_size; + + /* Decrypt Append*/ + e_ret_status = SFU_LL_FLASH_Read(fw_encrypted_chunk, (uint8_t *) fw_source_address, size); + if (e_ret_status != SFU_SUCCESS) + { + break; + } + if (size != 0U) + { + se_ret_status = SE_Decrypt_Append(&e_se_status, (uint8_t *)fw_encrypted_chunk, (int32_t)size, + fw_decrypted_chunk, (int32_t *)&fw_decrypted_chunk_size); + } + else + { + e_ret_status = SFU_SUCCESS; + fw_decrypted_chunk_size = 0U; + } + if ((se_ret_status == SE_SUCCESS) && (e_se_status == SE_OK) && (fw_decrypted_chunk_size == size)) + { + /* Erase Page */ + if ((pass_index == erase_index) + || (pass_index == ((SFU_IMG_IMAGE_OFFSET + (pFwImageHeader->PartialFwOffset % SLOT_SIZE(SLOT_SWAP))) / + sizeof(fw_decrypted_chunk)))) + { + (void) SFU_LL_SECU_IWDG_Refresh(); + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *)fw_dest_erase_address, + SLOT_SIZE(SLOT_SWAP)) ; + erase_index += NumberOfChunkPerSwap; + fw_dest_erase_address += SLOT_SIZE(SLOT_SWAP); + } + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + if (e_ret_status == SFU_SUCCESS) + { + /* + * For last pass with remaining size not aligned on 16 bytes : Set dimension AFTER decrypt to the appropriate + * length for FLASH programming. + * Example: 64-bit length for L4. + */ + if ((size & ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - 1U)) != 0U) + { + /* + * By construction, SFU_IMG_CHUNK_SIZE is a multiple of sizeof(SFU_LL_FLASH_write_t) so there is no risk to + * read out of the buffer + */ + oldsize = size; + size = size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - (size % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); + while (oldsize < size) + { + fw_decrypted_chunk[oldsize] = 0xFF; + oldsize++; + } + } + + /* Write Decrypted Data in Flash - size has to be 32-bit aligned */ + e_ret_status = SFU_LL_FLASH_Write(&flash_if_status, (uint8_t *)fw_dest_address_write, fw_decrypted_chunk, + size); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_WRITE_FAILED); + + if (e_ret_status == SFU_SUCCESS) + { + /* Update flash pointer */ + fw_dest_address_write += (size); + + /* Update source pointer */ + fw_source_address += size; + fw_decrypted_total_size += size; + (void) memset(fw_decrypted_chunk, 0xff, sizeof(fw_decrypted_chunk)); + pass_index += 1U; + + } + } + } + } + } + +#if (SFU_IMAGE_PROGRAMMING_TYPE == SFU_ENCRYPTED_IMAGE) +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t %d bytes of ciphertext decrypted.", fw_decrypted_total_size); +#endif /* SFU_VERBOSE_DEBUG_MODE */ +#endif /* SFU_ENCRYPTED_IMAGE */ + + if ((se_ret_status == SE_SUCCESS) && (e_ret_status == SFU_SUCCESS) && (e_se_status == SE_OK)) + { + /* Do the Finalization, check the authentication TAG*/ + fw_tag_len = sizeof(fw_tag_output); + se_ret_status = SE_Decrypt_Finish(&e_se_status, fw_tag_output, (int32_t *)&fw_tag_len); + if ((se_ret_status != SE_SUCCESS) || (e_se_status != SE_OK)) + { + e_ret_status = SFU_ERROR; +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t Decrypt fails at Finalization stage."); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + else + { + /* erase the remaining part of the image after shifting inside dwl slot */ + if (pass_index <= NumberOfChunkPerSwap) + { + fw_dest_erase_address = SlotStartAdd[DwlSlot]; + } + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *)fw_dest_erase_address, SLOT_SIZE(SLOT_SWAP)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + } + } + else + { + e_ret_status = SFU_ERROR; + } + return e_ret_status; +} + + +/** + * @brief check trailer validity to allow resume installation. + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @param pValidHeader: pointer in ram to header of valid fw to backup + * @param pTestHeader: pointer in ram to header of fw to test + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +static SFU_ErrorStatus FirmwareToResume(uint32_t ActiveSlot, uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pValidHeader, + SE_FwRawHeaderTypeDef *pTestHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t fw_header_trailer_valid[SE_FW_HEADER_TOT_LEN]; + uint8_t fw_header_trailer_test[SE_FW_HEADER_TOT_LEN]; + uint8_t fw_header_active_slot[SE_FW_HEADER_TOT_LEN]; + + /* + * Initial conditions to be fulfilled : + * - Trailer magic is present + * - Active slot number is correct + * - test header from trailer is signed + */ + + /* check trailer Magic */ + e_ret_status = CheckTrailerMagic(DwlSlot); + if (e_ret_status == SFU_SUCCESS) + { + /* Populate the pTestHeader and verify it the active slot is correct */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_trailer_test, TRAILER_HDR_TEST(DwlSlot), sizeof(fw_header_trailer_test)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Populate pTestHeader parameter */ + e_ret_status = ParseFWInfo(pTestHeader, fw_header_trailer_test); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Active slot number correct ? + As example : if magic is SFU2 active slot should be SLOT_ACTIVE_2 */ + if (ActiveSlot == SFU_IMG_GetFwImageSlot(pTestHeader)) + { + /* Check header test field in trailer is signed */ + e_ret_status = VerifyHeaderSignature((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header_trailer_test); + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t No resume required : TRAILER_HDR_TEST not valid!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + e_ret_status = SFU_ERROR; + } + } + + if (e_ret_status != SFU_SUCCESS) + { + return SFU_ERROR; + } + + /* Read header in active slot if any */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_active_slot, (uint8_t *) SlotHeaderAdd[ActiveSlot], + sizeof(fw_header_active_slot)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + + if (e_ret_status == SFU_SUCCESS) + { + /* Verify the header signature in active slot */ + e_ret_status = VerifyHeaderSignature((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header_active_slot); + } + if (e_ret_status == SFU_SUCCESS) + { + /* Header in active slot is signed and validated, in protected area: it can be trusted. */ + + /* Populate pValidHeader parameter */ + e_ret_status = ParseFWInfo(pValidHeader, fw_header_active_slot); + + if (e_ret_status == SFU_SUCCESS) + { + /* Read header valid field in trailer */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_trailer_valid, TRAILER_HDR_VALID(DwlSlot), + sizeof(fw_header_trailer_valid)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Check if header in active slot is same as header valid in trailer */ + if (memcmp(fw_header_active_slot, fw_header_trailer_valid, SE_FW_AUTH_LEN) != 0) + { + /* + * Header in active slot is not identical to header valid field: + * Either install is already complete (if header in active slot is same as header test field in trailer), + * or there is hack tentative. + * In both cases, resume install must not be triggered. + */ +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t No resume required : TRAILER_HDR_VALID already stored in active slot!"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + e_ret_status = SFU_ERROR; + } + else + { + /* Check candidate image version */ + e_ret_status = SFU_IMG_CheckFwVersion(ActiveSlot, pValidHeader->FwVersion, pTestHeader->FwVersion); + } + } + /* At this point, if (e_ret_status == SFU_SUCCESS) then resume of installation is allowed */ + } + else + { + /* + * Header in active slot is not valid. + * It is considered this can not be hack attempt, because header in active slot is in + * protected area. + * Possible reasons: + * - Swap has been interrupted during very first image installation (active slot was empty) + * - Swap has been interrupted during reconstitution of first sector of active slot + * If header test field in trailer is signed and with proper version, we resume install. + */ + + /* Read header valid field in trailer */ + e_ret_status = SFU_LL_FLASH_Read(fw_header_trailer_valid, TRAILER_HDR_VALID(DwlSlot), + sizeof(fw_header_trailer_valid)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (e_ret_status == SFU_SUCCESS) + { + /* Check header valid field in trailer is signed */ + e_ret_status = VerifyHeaderSignature((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header_trailer_valid); + + if (e_ret_status == SFU_SUCCESS) + { + /* active slot was containing an active image */ + + /* Populate pValidHeader parameter */ + e_ret_status = ParseFWInfo(pValidHeader, fw_header_trailer_valid); + + if (e_ret_status == SFU_SUCCESS) + { + /* Check candidate image version */ + e_ret_status = SFU_IMG_CheckFwVersion(ActiveSlot, pValidHeader->FwVersion, pTestHeader->FwVersion); + } + } + else + { + /* active slot was empty or was containing bricked Fw image */ + e_ret_status = SFU_SUCCESS; + } + } + + /* At this point, if (e_ret_status == SFU_SUCCESS) then resume of installation is allowed */ + } + + return e_ret_status; +} + + +#if defined(ENABLE_IMAGE_STATE_HANDLING) +/** + * @brief Check that there is an Image to Install + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer to fw header to install + * @retval SFU_SUCCESS if Image can be installed, a SFU_ERROR otherwise. + */ +static SFU_ErrorStatus FirmwareToInstall(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_ErrorStatus e_ret_status_se; + SE_StatusTypeDef e_se_status; + uint32_t trailer_begin = (uint32_t) TRAILER_BEGIN(DwlSlot); + uint32_t end_of_test_image; + SE_FwStateTypeDef image_state = FWIMG_STATE_INVALID; + + /* + * The anti-rollback check is implemented at installation stage (SFU_IMG_InstallNewVersion) + * to be able to handle a specific error cause. + */ + /* check swap header */ + e_ret_status = CheckAndGetFWHeader(DwlSlot, pFwImageHeader); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status_se = SE_SFU_IMG_GetActiveFwState(&e_se_status, DwlSlot, &image_state); + if (e_ret_status_se == SE_SUCCESS) + { + /* Control the size of image to be installed taking into account trailers */ + end_of_test_image = (SlotStartAdd[DwlSlot] + pFwImageHeader->FwSize + SFU_IMG_IMAGE_OFFSET); + + if ((image_state != FWIMG_STATE_NEW) || (trailer_begin < end_of_test_image)) + { + /* + * These error causes are not memorized in the BootInfo area because there won't be any error handling + * procedure. + * If this function returns that no new firmware can be installed (as this may be a normal case). + */ + e_ret_status = SFU_ERROR; + +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (image_state != FWIMG_STATE_NEW) + { + TRACE("\r\n\t The image state of SLOT_DWL_%d is not FWIMG_STATE_NEW!", DwlSlot); + } + if (trailer_begin < end_of_test_image) + { + TRACE("\r\n\t The binary image to be installed overlap with the trailer area!"); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + else + { + e_ret_status = SFU_SUCCESS; + } + } + else + { + e_ret_status = SFU_ERROR; + } + } + return e_ret_status; +} + +#else + +/** + * @brief Check that there is an Image to Install + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer to fw header to install + * @retval SFU_SUCCESS if Image can be installed, a SFU_ERROR otherwise. + */ +static SFU_ErrorStatus FirmwareToInstall(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t *p_header_swap; + uint8_t fw_header_dwl_slot[SE_FW_HEADER_TOT_LEN]; + uint32_t trailer_begin = (uint32_t) TRAILER_BEGIN(DwlSlot); + uint32_t end_of_test_image; + int32_t ret; + /* + * The anti-rollback check is implemented at installation stage (SFU_IMG_InstallNewVersion) + * to be able to handle a specific error cause. + */ + + /* check swap header */ + e_ret_status = CheckAndGetFWHeader(SLOT_SWAP, pFwImageHeader); + if (e_ret_status == SFU_SUCCESS) + { + /* compare the header in dwl slot with the header in swap */ + p_header_swap = (uint8_t *) pFwImageHeader; + e_ret_status = SFU_LL_FLASH_Read(fw_header_dwl_slot, (uint8_t *) SlotStartAdd[DwlSlot], + sizeof(fw_header_dwl_slot)); + if (e_ret_status == SFU_SUCCESS) + { + /* image header in dwl slot not consistent with swap header */ + end_of_test_image = (SlotStartAdd[DwlSlot] + pFwImageHeader->FwSize + + SFU_IMG_IMAGE_OFFSET); + + /* the header in swap must be the same as the header in dwl slot */ + ret = memcmp(fw_header_dwl_slot, p_header_swap, SE_FW_HEADER_TOT_LEN); + + /* Check if there is enough room for the trailers */ + if ((trailer_begin < end_of_test_image) || (ret != 0)) + { + /* + * These error causes are not memorized in the BootInfo area because there won't be any error handling + * procedure. + * If this function returns that no new firmware can be installed (as this may be a normal case). + */ + e_ret_status = SFU_ERROR; + +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (trailer_begin < end_of_test_image) + { + TRACE("\r\n\t The binary image to be installed overlap with the trailer area!"); + } /* check next error cause */ + + if (ret != 0) + { + TRACE("\r\n\t The headers in dwl slot and swap area do not match!"); + } /* else do not print the message(s) again */ +#endif /* SFU_VERBOSE_DEBUG_MODE */ + } + else + { + e_ret_status = SFU_SUCCESS; + } + } + } + return e_ret_status; +} +#endif /* (ENABLE_IMAGE_STATE_HANDLING) */ + + +/** + * @brief Prepares the Candidate FW image for Installation. + * This stage depends on the supported features: in this example this consists in decrypting the candidate + * image. + * @note Even if the Firmware Image is in clear format the decrypt function is called. + * But, in this case no decrypt is performed, it is only a set of copy operations + * to organize the Firmware Image in FLASH as expected by the swap procedure. + * @param DwlSlot identification of the downloaded area + * @param pFwImageHeader pointer to fw header to install + * @retval SFU_SUCCESS if successful,SFU_ERROR error otherwise. + */ +static SFU_ErrorStatus PrepareCandidateImageForInstall(uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pFwImageHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + + /* + * Control if there is no additional code beyond the firmware image (malicious SW) + */ + e_ret_status = VerifySlot((uint8_t *) SlotStartAdd[DwlSlot], SLOT_SIZE(DwlSlot), + pFwImageHeader->PartialFwSize + (pFwImageHeader->PartialFwOffset % + SLOT_SIZE(SLOT_SWAP))); + + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_ADDITIONAL_CODE_ERR); + return e_ret_status; + } + + /* + * Pre-condition: all checks have been performed, + * so all FWIMG module variables are populated. + * Now we can decrypt in FLASH. + * + * Initial FLASH state (focus on dwl slot and swap area): + * + * Depending on partial FW offset, we can have: + * : {Candidate Image Header + encrypted FW - page k} + * {encrypted FW - page k+1} + * ..... + * {encrypted FW - page k+N} + * ..... + * + * or: + * : {Candidate Image Header } + * {encrypted FW - page k} + * ..... + * {encrypted FW - page k+N} + * ..... + * + * + * : {Candidate Image Header} + * + */ + e_ret_status = DecryptImageInDwlSlot(DwlSlot, pFwImageHeader); + + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_DECRYPT_ERR); + return e_ret_status; + } + + /* + * At this step, the FLASH content looks like this: + * + * : {decrypted FW - data from page k+1 in page 0} + * {decrypted FW - data from page k+2 in page 1} + * ..... + * {decrypted FW - data from page k+N in page N-1} + * {page N is now empty} + * ..... + * + * + * : {No Header (shift) + decrypted FW data from page k} + * + * + * The Candidate FW image has been decrypted + * and a "hole" has been created in dwl slot to be able to swap. + */ + + e_ret_status = VerifyFwSignatureAfterDecrypt(&e_se_status, DwlSlot, pFwImageHeader); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_SIGNATURE_ERR); + } + + /* Return the result of this preparation */ + return (e_ret_status); +} + + +/** + * @brief Install the new version + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @param pValidHeader: pointer in ram to header of valid fw to backup + * @param pTestHeader: pointer in ram to header of fw to test + * @retval SFU_SUCCESS if successful,SFU_ERROR error otherwise. + */ +static SFU_ErrorStatus InstallNewVersion(uint32_t ActiveSlot, uint32_t DwlSlot, SE_FwRawHeaderTypeDef *pValidHeader, + SE_FwRawHeaderTypeDef *pTestHeader) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* + * At this step, the FLASH content looks like this: + * + * : {decrypted FW - data from page k+1 in page 0} + * {decrypted FW - data from page k+2 in page 1} + * ..... + * {decrypted FW - data from page k+N in page N-1} + * {page N is now empty} + * ..... + * + * + * : {No Header (shift) + decrypted FW data from page k} + * + * + */ + + /* erase "swap area" size at the end of dwl slot */ + e_ret_status = EraseSlotIndex(DwlSlot, (TRAILER_INDEX(DwlSlot) - 1U)); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_TRAILER_ERASING_ERR); + return e_ret_status; + } + + /* + * At this step, the FLASH content looks like this: + * + * : {decrypted FW - data from page k+1 in page 0} + * {decrypted FW - data from page k+2 in page 1} + * ..... + * {decrypted FW - data from page k+N in page N-1} + * {page N is now empty} + * ..... + * {at least the swap area size at the end of the last page of dwl slot is empty } + * + * + * : {No Header (shift) + decrypted FW data from page 0} + * + * + */ + + + /* write trailer */ + e_ret_status = WriteTrailerHeader(DwlSlot, pValidHeader, pTestHeader); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_TRAILER_UPDATE_ERR); + return e_ret_status; + } + + /* + * At this step, the FLASH content looks like this: + * + * : {decrypted FW - data from page k+1 in page 0} + * {decrypted FW - data from page k+2 in page 1} + * ..... + * {decrypted FW - data from page k+N in page N-1} + * {page N is now empty} + * ..... + * {the last page of dwl slot ends with the trailer magic patterns and the free space for the trailer + * info} + * + * + * : {No Header (shift) + decrypted FW data from page 0} + * + * + * The trailer magic patterns is ActiveFwHeader|CandidateFwHeader|SWAPmagic. + * This is followed by a free space to store the trailer info (N*CPY_TO_ACTIVE_SLOT) and (N*CPY_TO_DWL_SLOT): + * + *<------------------------------------------ Last page of dwl slot ---------------------------------------> + * |HEADER_TOT_LEN|HEADER_TOT_LEN|MAGIC_LENGTH|MAGIC_LENGTH |N*sizeof(FLASH_write_t)|N*sizeof(FLASH_write_t) + * | header 1 | header 2 |SWAP magic |CLEAN pattern|N*CPY_TO_ACTIVE_SLOT | N*CPY_TO_DWL_SLOT + * + */ + + /* swap */ + e_ret_status = SwapFirmwareImages(ActiveSlot, DwlSlot, pTestHeader); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_FWIMG_SWAP_ERR); + return e_ret_status; + } + +#ifdef ENABLE_IMAGE_STATE_HANDLING + /* Update fingerprint from previous FW image */ + UpdateHeaderFingerPrint(&fw_image_header_to_test, &fw_image_header_validated); +#endif /* ENABLE_IMAGE_STATE_HANDLING */ + + /* Validate immediately the new active FW */ + e_ret_status = SFU_IMG_Validation(ActiveSlot, pTestHeader); + if (SFU_SUCCESS != e_ret_status) + { + SFU_EXCPT_SetError(SFU_EXCPT_HEADER_VALIDATION_ERR); + return e_ret_status; + } + + /* clear swap pattern */ + e_ret_status = CleanMagicValue(DwlSlot); + if (e_ret_status != SFU_SUCCESS) + { + /* Memorize the error */ + SFU_EXCPT_SetError(SFU_EXCPT_FWIMG_MAGIC_ERR); + return e_ret_status; + } + + return e_ret_status; /* Leave the function now */ +} + +/* Functions Definition : services ------------------------------------------- */ +/** + * @brief FW Image Handling (FWIMG) initialization function from swap process. + * Checks the validity of the settings related to image handling (slots size and alignments...). + * @note The system initialization must have been performed before calling this function (flash driver ready to be + * used...etc...). + * Must be called first (and once) before calling the other Image handling services. + * @param None. + * @retval SFU_IMG_InitStatusTypeDef SFU_IMG_INIT_OK if successful, an error code otherwise. + */ +SFU_IMG_InitStatusTypeDef SFU_IMG_CheckSwapImageHandling(void) +{ + SFU_IMG_InitStatusTypeDef e_ret_status = SFU_IMG_INIT_OK; + uint32_t i; + + /* + * Sanity check: let's make sure the slot sizes are correct + * to avoid discrepancies between linker definitions and constants in sfu_fwimg_regions.h + */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { + if (!(SFU_IMG_REGION_IS_MULTIPLE(SLOT_SIZE(SLOT_ACTIVE_1 + i), SLOT_SIZE(SLOT_SWAP)))) + { + TRACE("\r\n= [FWIMG] SLOT_ACTIVE_%d size (%d) must be a multiple of swap size (%d)\r\n", + SLOT_ACTIVE_1 + i, SLOT_SIZE(SLOT_ACTIVE_1 + i), SLOT_SIZE(SLOT_SWAP)); + e_ret_status = SFU_IMG_INIT_SLOTS_SIZE_ERROR; + } + } + } + + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { + if (SlotStartAdd[SLOT_DWL_1 + i] != 0U) + { + if (!(SFU_IMG_REGION_IS_MULTIPLE(SLOT_SIZE(SLOT_DWL_1 + i), SLOT_SIZE(SLOT_SWAP)))) + { + TRACE("\r\n= [FWIMG] SLOT_DWL_%d size (%d) must be a multiple of swap size (%d)\r\n", + i + 1U, SLOT_SIZE(SLOT_DWL_1 + i), SLOT_SIZE(SLOT_SWAP)); + e_ret_status = SFU_IMG_INIT_SLOTS_SIZE_ERROR; + } + } + } + + /* + * Sanity check: let's make sure the slot size is correct with regards to the swap procedure constraints. + * The swap procedure cannot succeed if the trailer info size is bigger than what a chunk used for swapping can carry. + */ + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { + if (SlotStartAdd[SLOT_DWL_1 + i] != 0U) + { + if (((int32_t)(SFU_IMG_CHUNK_SIZE - (TRAILER_INDEX(SLOT_DWL_1 + i) * sizeof(SFU_LL_FLASH_write_t)))) < 0) + { + e_ret_status = SFU_IMG_INIT_SWAP_SETTINGS_ERROR; + TRACE("\r\n= [FWIMG] %d bytes required for the swap metadata of SLOT_DWL_%d is too much\r\n", + (TRAILER_INDEX(SLOT_DWL_1 + i) * sizeof(SFU_LL_FLASH_write_t)), i + 1U); + } /* else the swap settings are fine from a metadata size perspective */ + } + } + + /* + * Sanity check: let's make sure the swap size is correct with regards to the swap procedure constraints. + * The swap size must be a multiple of the chunks size used to do the swap. + */ +#if defined(__GNUC__) + __IO uint32_t swap_size = SLOT_SIZE(SLOT_SWAP), swap_chunk = SFU_IMG_CHUNK_SIZE; + if (0U != ((uint32_t)(swap_size % swap_chunk))) +#else + if (0U != ((uint32_t)(SLOT_SIZE(SLOT_SWAP) % SFU_IMG_CHUNK_SIZE))) +#endif /* __GNUC__ */ + { + e_ret_status = SFU_IMG_INIT_SWAP_SETTINGS_ERROR; + TRACE("\r\n= [FWIMG] The swap procedure uses chunks of %d bytes but the swap size (%d) is not a multiple\r\n", + SFU_IMG_CHUNK_SIZE, SLOT_SIZE(SLOT_SWAP)); + } /* else the swap settings are fine from a chunk size perspective */ + + /* + * Sanity check: let's make sure the chunks used for the swap procedure are big enough with regards to the offset + * giving the start @ of the firmware + */ + if (((int32_t)(SFU_IMG_CHUNK_SIZE - SFU_IMG_IMAGE_OFFSET)) < 0) + { + e_ret_status = SFU_IMG_INIT_SWAP_SETTINGS_ERROR; + TRACE("\r\n= [FWIMG] The swap procedure uses chunks of %d bytes but the firmware start offset is %d bytes\r\n", + SFU_IMG_CHUNK_SIZE, SFU_IMG_IMAGE_OFFSET); + } /* else the swap settings are fine from a firmware start offset perspective */ + + /* + * Sanity check: let's make sure SWAP slot is properly aligned with regards to flash constraints + */ + + if (!IS_ALIGNED(SlotStartAdd[SLOT_SWAP])) + { + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + TRACE("\r\n= [FWIMG] swap (%x) is not properly aligned\r\n", + SlotStartAdd[SLOT_SWAP]); + } /* else swap is properly aligned */ + + /* + * Sanity check: let's make sure the swap area does not overlap SB code area protected by WRP) + */ + if (((SlotStartAdd[SLOT_SWAP] - FLASH_BASE) / FLASH_PAGE_SIZE) <= SFU_PROTECT_WRP_PAGE_END_1) + { + TRACE("\r\n= [FWIMG] SWAP overlaps SBSFU code area protected by WRP\r\n"); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + + /* + * Sanity check: let's make sure the KMS NVM area does not overlap Swap area) + */ + if (!(((SlotStartAdd[SLOT_SWAP]) > KMS_DATASTORAGE_END) + || ((SlotEndAdd[SLOT_SWAP]) < (KMS_DATASTORAGE_START)))) + { + TRACE("\r\n= [FWIMG] KMS NVM area overlaps Swap area\r\n"); + e_ret_status = SFU_IMG_INIT_FLASH_CONSTRAINTS_ERROR; + } + + /* FWIMG core initialization completed */ + return e_ret_status; +} + + + +/** + * @brief Checks if there is a pending firmware installation. + * 3 situations can occur: + * A. Pending firmware installation: a firmware is ready to be installed but the installation has never been + * triggered so far. + * B. Pending firmware installation resume: a firmware installation has been interrupted and a resume procedure + * is required to finalize installation. + * C. No firmware installation pending + * @note The anti-rollback check is not taken into account at this stage. + * But, if the firmware to be installed already carries some metadata (VALID tag) a newly downloaded firmware + * should not have then the installation is not considered as pending. + * @note This function populates the FWIMG module variables: + * - case SFU_IMG_FWUPDATE_STOPPED : fw_image_header_to_test & fw_image_header_validated + * - case SFU_IMG_FWIMAGE_TO_INSTALL : fw_image_header_to_test + * - case SFU_IMG_NO_FWUPDATE : none + * @param pDwlSlotToInstall identification of the downloaded slot to install + * @param pActiveSlotToResume identification of the active slot to resume + * @param pActiveSlotToRollback identification of the active slot to rollback + * @retval SFU_IMG_ImgInstallStateTypeDef Pending Installation status (pending install, pending resume install, no + * pending action) + */ +SFU_IMG_ImgInstallStateTypeDef SFU_IMG_CheckPendingInstallation(uint32_t *pDwlSlotToInstall, \ + uint32_t *pActiveSlotToResume, \ + uint32_t *pActiveSlotToRollback) +{ + uint32_t i; + uint32_t j; +#ifdef ENABLE_IMAGE_STATE_HANDLING + SE_FwStateTypeDef master_slot_state = FWIMG_STATE_INVALID; + SE_StatusTypeDef e_se_status; +#endif /* ENABLE_IMAGE_STATE_HANDLING */ + + /* + * The order of the checks is important: + * + * A. Check if a FW update has been interrupted first. + * This check is based on the content of the trailer area and the validity of the update image. + * + * B. Check if a Firmware image is waiting to be installed. + */ + + /* Init values */ + *pActiveSlotToResume = SLOT_INACTIVE; + *pActiveSlotToRollback = SLOT_INACTIVE; + *pDwlSlotToInstall = SLOT_INACTIVE; + +#ifdef ENABLE_IMAGE_STATE_HANDLING + /* + * Read MASTER_SLOT state (if configured == (!= 255)) : + * In case of VALID_ALL state, all other slots in SELF_TEST should be validated + * Else all other slots in SELF_TEST are invalidated + */ + if (MASTER_SLOT != 0xFFU) + { + if (SFU_SUCCESS == SFU_IMG_DetectFW(MASTER_SLOT)) + { + if (SE_SFU_IMG_GetActiveFwState(&e_se_status, MASTER_SLOT, &master_slot_state) != SE_SUCCESS) + { + master_slot_state = FWIMG_STATE_INVALID; + } + } + } +#endif /* ENABLE_IMAGE_STATE_HANDLING */ + + /* Check image installation stopped or installation to be done + =========================================================== */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_ACTIVE_1 + i] != 0U) + { +#ifdef ENABLE_IMAGE_STATE_HANDLING + /* Rollback if seltftest not validated + =================================== */ + if (SFU_SUCCESS == FirmwareToRollback(SLOT_ACTIVE_1 + i, master_slot_state)) + { + /* The firmware state is either FWIMG_STATE_SELFTEST or FWIMG_STATE_INVALID + * Rollback is required + * Stop at first occurrence : next ones if any will be resumed after reset + */ + *pActiveSlotToRollback = SLOT_ACTIVE_1 + i; + return SFU_IMG_FWIMAGE_ROLLBACK; + } +#endif /* ENABLE_IMAGE_STATE_HANDLING */ + + /* Check trailer valide : installation stopped ? + ============================================= */ + for (j = 0U; j < SFU_NB_MAX_DWL_AREA; j++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_DWL_1 + j] != 0U) + { + if (SFU_SUCCESS == FirmwareToResume(SLOT_ACTIVE_1 + i, SLOT_DWL_1 + j, &fw_image_header_validated, + &fw_image_header_to_test)) + { + /* A Firmware Update has been stopped + * fw_image_header_to_test & fw_image_header_validated have been populated + * Stop at first occurrence : next ones if any will be resumed after reset + */ + *pActiveSlotToResume = SLOT_ACTIVE_1 + i; + *pDwlSlotToInstall = SLOT_DWL_1 + j; + return SFU_IMG_FWUPDATE_STOPPED; + } + } + } + } + } + + /* Install new firmware if requested in the swap + ============================================= */ + for (j = 0U; j < SFU_NB_MAX_DWL_AREA; j++) + { + /* Slot configured ? */ + if (SlotStartAdd[SLOT_DWL_1 + j] != 0U) + { + if (SFU_SUCCESS == FirmwareToInstall(SLOT_DWL_1 + j, &fw_image_header_to_test)) + { + /* + * A Firmware is available for installation: + * fw_image_header_to_test has been populated + * Stop at first occurrence : next ones if any will be installed after reset + */ + *pDwlSlotToInstall = SLOT_DWL_1 + j; + return SFU_IMG_FWIMAGE_TO_INSTALL; + } + } + } + + return SFU_IMG_NO_FWUPDATE; +} + +/** + * @brief Installs a new firmware, performs the post-installation checks and sets the metadata to tag this firmware as + * valid if the checks are successful. + * The anti-rollback check is performed and errors are memorized in the bootinfo area, but no action is taken + * in this procedure. + * Cryptographic operations are used (if enabled): the firmware is decrypted and its authenticity is checked + * afterwards if the cryptographic scheme allows this (signature check for instance). + * The detailed errors are memorized in bootinfo area to be processed as critical errors if needed. + * This function modifies the FLASH content. + * If this procedure is interrupted during image preparation stage (e.g.: switch off) it cannot be resumed. + * If it is interrupted during installation stage, it can be resumed. + * @note It is up to the caller to make sure the conditions to call this primitive are met (no check performed before + * running the procedure): SFU_IMG_CheckPendingInstallation, SFU_IMG_CheckCandidateVersion should be called + * first. + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_TriggerImageInstallation(uint32_t DwlSlot) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t *pbuffer; + uint32_t active_slot = 0U; + + active_slot = SFU_IMG_GetFwImageSlot(&fw_image_header_to_test); + + /* + * The preparation stage consists in decrypting the candidate firmware image. + * fw_image_header_to_test is already populated after SFU_IMG_CheckPendingInstallation() call. + */ + e_ret_status = PrepareCandidateImageForInstall(DwlSlot, &fw_image_header_to_test); + if (SFU_SUCCESS != e_ret_status) + { + goto exit; + } + + /* + * Populate fw_image_header_validated + */ + if (SFU_SUCCESS == e_ret_status) + { + pbuffer = (uint8_t *) SlotHeaderAdd[active_slot]; + e_ret_status = SFU_LL_FLASH_Read((uint8_t *) &fw_image_header_validated, pbuffer, + sizeof(fw_image_header_validated)); + } + + /* + * Installing the new firmware image consists in swapping the 2 FW images. + */ + if (SFU_SUCCESS == e_ret_status) + { + e_ret_status = InstallNewVersion(active_slot, DwlSlot, &fw_image_header_validated, &fw_image_header_to_test); + } + +exit: + /* Erase downloaded FW in case of authentication/integrity error + Erase downloaded FW also in case of installation issue to avoid any infinite loop */ + if (SFU_SUCCESS != e_ret_status) + { + (void) SFU_IMG_EraseDownloadedImg(DwlSlot); + } + +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status == SFU_SUCCESS) + { + TRACE("\r\n\t Installation procedure completed."); + } + else + { + TRACE("\r\n\t Installation procedure cannot be finalized!"); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + /* return the installation result */ + return (e_ret_status); +} + +/** + * @brief Resume installation of new valid firmware after installation failure. + * If this procedure is interrupted before its completion (e.g.: switch off) it can be resumed. + * This function is dedicated (only) to the resume of installation when a new firmware installation is stopped + * before its completion. + * This function does not handle explicitly the metadata tagging the firmware as valid: these metadata must + * have been preserved during the installation procedure. + * This function modifies the FLASH content. + * @note It is up to the caller to make sure the conditions to call this primitive are met (no check performed before + * running the procedure): need to make sure an installation has been interrupted. + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_TriggerResumeInstallation(uint32_t ActiveSlot, uint32_t DwlSlot) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* + * resume swap process + * fw_image_header_to_test is already populated after SFU_IMG_CheckPendingInstallation()call. + */ + e_ret_status = SwapFirmwareImages(ActiveSlot, DwlSlot, &fw_image_header_to_test); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_FWIMG_SWAP_ERR); + goto exit; + } + +#ifdef ENABLE_IMAGE_STATE_HANDLING + /* Update fingerprint from previous FW image */ + UpdateHeaderFingerPrint(&fw_image_header_to_test, &fw_image_header_validated); +#endif /* ENABLE_IMAGE_STATE_HANDLING */ + + /* Validate immediately the new active FW */ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_IMG_Validation(ActiveSlot, &fw_image_header_to_test); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_HEADER_VALIDATION_ERR); + goto exit; + } + } + + /* clear swap pattern */ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = CleanMagicValue(DwlSlot); + if (e_ret_status != SFU_SUCCESS) + { + /* Memorize the error */ + SFU_EXCPT_SetError(SFU_EXCPT_FWIMG_MAGIC_ERR); + goto exit; + } + } + +exit: + /* Erase downloaded FW in case of installation issue to avoid any infinite loop */ + if (SFU_SUCCESS != e_ret_status) + { + (void) SFU_IMG_EraseDownloadedImg(DwlSlot); + } + +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status == SFU_SUCCESS) + { + TRACE("\r\n\t Resume procedure completed."); + } + else + { + TRACE("\r\n\t Resume procedure cannot be finalized!"); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + return e_ret_status; +} + +#ifdef ENABLE_IMAGE_STATE_HANDLING +/** + * @brief Executes a rollback to the original firmware if a firmware update fails + * @param ActiveSlot identification of the active image + * @param DwlSlot identification of the downloaded area + * @retval SFU_ErrorStatus SFU_SUCCESS if the rollback is successful, error code otherwise + */ +SFU_ErrorStatus SFU_IMG_TriggerRollbackInstallation(uint32_t ActiveSlot, uint32_t DwlSlot) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t zero_buffer[32U] = {0U}; + SE_FwRawHeaderTypeDef active_header; + SE_FwRawHeaderTypeDef dwl_header; + SFU_FLASH_StatusTypeDef flash_if_status; + + + /* Verify slot 1 header is from fw that triggered the update */ + /* Backed-up header is in flash Slot1 at pHdr address */ + /* Load current header (start of Slot 0, normally behind the firewall) */ + e_ret_status = SFU_LL_FLASH_Read((uint8_t *)&active_header, (uint8_t *) SlotHeaderAdd[ActiveSlot], + sizeof(dwl_header)); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_READ_FAILED); + if (SFU_SUCCESS == e_ret_status) + { + /* if fingerprint is 0x00 we cannot do rollback */ + if (0U == memcmp(active_header.PrevHeaderFingerprint, zero_buffer, sizeof(active_header.PrevHeaderFingerprint))) + { + e_ret_status = SFU_ERROR; + SFU_EXCPT_SetError(SFU_EXCPT_FWIMG_ROLLBACK_PREV_ID_ERR); + goto exit; + } + } + + /* Get and check previous FW header saved in DWL slot + then compare header signature with active slot header finger print */ + if (SFU_SUCCESS == e_ret_status) + { + e_ret_status = CheckAndGetFWHeader(DwlSlot, &dwl_header); + if (SFU_SUCCESS == e_ret_status) + { + /* Fingerprint of active firmware should be the signature of previous firmware */ + if (0 != memcmp(active_header.PrevHeaderFingerprint, dwl_header.HeaderSignature, + sizeof(active_header.PrevHeaderFingerprint))) + { + e_ret_status = SFU_ERROR; + SFU_EXCPT_SetError(SFU_EXCPT_FWIMG_ROLLBACK_PREV_ID_ERR); + goto exit; + } + } + } + + /* Rollback execution */ + if (SFU_SUCCESS == e_ret_status) + { + e_ret_status = RollbackInstallation(ActiveSlot, DwlSlot, &dwl_header); + if (e_ret_status != SFU_SUCCESS) + { + SFU_EXCPT_SetError(SFU_EXCPT_FWIMG_ROLLBACK_ERR); + goto exit; + } + } + +exit: + if (e_ret_status == SFU_SUCCESS) + { + /* Rollback is complete, now erase downloaded image to prevent an attempt to + * reinstall + */ + (void) SFU_IMG_EraseDownloadedImg(DwlSlot); + } + else + { + /* Erase the header of active slot to avoid any infinite loop */ + e_ret_status = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotHeaderAdd[ActiveSlot], + SFU_IMG_IMAGE_OFFSET); + STATUS_FWIMG(e_ret_status == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + } + +#if defined(SFU_VERBOSE_DEBUG_MODE) + if (e_ret_status == SFU_SUCCESS) + { + TRACE("\r\n\t Rollback procedure completed."); + } + else + { + TRACE("\r\n\t Rollback procedure cannot be finalized!"); + } +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + return e_ret_status; +} + +/** + * @brief Updates the state of the current firmware + * @param SlotNumber index of the slot in the list + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_IMG_UpdateImageState(uint32_t SlotNumber) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + SE_ErrorStatus e_ret_status_se; + SE_FwStateTypeDef image_state = FWIMG_STATE_INVALID; + SE_StatusTypeDef e_se_status; + SE_FwStateTypeDef e_next_image_state; + + /* Read Image state : if image is new, set to self test + * + * An OTA image arrives on the device in the NEW state + * The bootloader switches the new image to SELFTEST state so + * that when the image boots it can detect that it should carry out the + * self test routine + */ + e_ret_status_se = SE_SFU_IMG_GetActiveFwState(&e_se_status, SlotNumber, &image_state); + if (e_ret_status_se == SE_SUCCESS) + { + if (image_state == FWIMG_STATE_NEW) + { + e_next_image_state = FWIMG_STATE_SELFTEST; + e_ret_status_se = SE_SFU_IMG_SetActiveFwState(&e_se_status, SlotNumber, &e_next_image_state); + if (e_ret_status_se == SE_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + } + else + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n\t SLOT_ACTIVE_%d state = %d failed to switch in FWIMG_STATE_SELFTEST", SlotNumber, + image_state); +#endif /* (SFU_VERBOSE_DEBUG_MODE) */ + e_ret_status = SFU_ERROR; + } + } + } + return e_ret_status; +} +#endif /* ENABLE_IMAGE_STATE_HANDLING */ + +/** + * @brief Get size of the trailer + * @note This area mapped at the end of a dwl slot is not available for the firmware image + * @param SlotNumber index of the slot in the list + * @retval Size of the trailer. + */ +uint32_t SFU_IMG_GetTrailerSize(uint32_t SlotNumber) +{ + return TRAILER_SIZE(SlotNumber); +} + +/** + * @brief Erase downloaded firmware in case of decryption/authentication/integrity error + * @param DwlSlot identification of the downloaded area + * @retval SFU_SUCCESS if successful, a SFU_ErrorStatus error otherwise. + */ +SFU_ErrorStatus SFU_IMG_EraseDownloadedImg(uint32_t DwlSlot) +{ + SFU_FLASH_StatusTypeDef flash_if_status; + SFU_ErrorStatus e_ret_status_dwl = SFU_ERROR; + SFU_ErrorStatus e_ret_status_swap = SFU_ERROR; + + e_ret_status_dwl = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotStartAdd[DwlSlot], + SLOT_SIZE(DwlSlot)); + STATUS_FWIMG(e_ret_status_dwl == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + e_ret_status_swap = SFU_LL_FLASH_Erase_Size(&flash_if_status, (uint8_t *) SlotStartAdd[SLOT_SWAP], + SLOT_SIZE(SLOT_SWAP)); + STATUS_FWIMG(e_ret_status_swap == SFU_ERROR, SFU_IMG_FLASH_ERASE_FAILED); + + return (((e_ret_status_swap != SFU_SUCCESS) || (e_ret_status_dwl != SFU_SUCCESS)) ? SFU_ERROR : SFU_SUCCESS); +} + +#endif /* !(SFU_NO_SWAP) */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c new file mode 100644 index 00000000..9083965c --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c @@ -0,0 +1,747 @@ +/** + ****************************************************************************** + * @file sfu_interface_crypto_scheme.c + * @author MCD Application Team + * @brief Secure Engine Interface module. + * This file provides set of firmware functions to manage SE Interface + * functionalities. These services are used by the bootloader. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" /* se_interface_bootloader.c is compiled in SBSFU project using main.h from this project */ +#include "se_low_level.h" /* This file is part of SE_CoreBin and adapts the Secure Engine (and its interface) to the + STM32 board specificities */ +#include "tkms.h" +#include "sfu_interface_crypto_scheme.h" +#include +#include "kms_platf_objects_interface.h" /* To get keys handle definitions */ + +/* Private defines -----------------------------------------------------------*/ +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) +#define GCM_TAGBITS_SIZE 128 +#define GCM_IVLEN_BITS 16 +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + +/* Private variables ---------------------------------------------------------*/ +CK_SESSION_HANDLE EncryptSession; +CK_SESSION_HANDLE DecryptSession; +CK_SESSION_HANDLE AuthenticateSession; +CK_SESSION_HANDLE VerifySession; +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) +static uint8_t *gcm_tag_header; +#endif /* SECBOOT_CRYPTO_SCHEME */ + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Get AES key handle. + * @param pxSE_Metadata Metadata that will be used to identify the keys. + * @param phAESKey pointer on AES key object handle + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) +static SE_ErrorStatus SFU_GetAESKeyObject(SE_FwRawHeaderTypeDef *pxSE_Metadata, CK_OBJECT_HANDLE *phAESKey) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + /* Each magic corresponds to a different key: + * SFUM_1 = SBSFU_KEY_1 + * SFUM_2 = SBSFU_KEY_2 + * SFUM_3 = SBSFU_KEY_3 + */ + if (memcmp(pxSE_Metadata->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) + { + *phAESKey = KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#if (SFU_NB_MAX_ACTIVE_IMAGE > 1U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) + { + *phAESKey = KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 1) */ +#if (SFU_NB_MAX_ACTIVE_IMAGE > 2U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) + { + *phAESKey = KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 2) */ + else + { + e_ret_status = SE_ERROR; + } + + return e_ret_status; +} +#endif /* ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) */ + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) +/** + * @brief Get ECDSA key handle. + * @param pxSE_Metadata Metadata that will be used to identify the keys. + * @param phAESKey pointer on AES key object handle + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +static SE_ErrorStatus SFU_GetECDSAKeyObject(SE_FwRawHeaderTypeDef *pxSE_Metadata, CK_OBJECT_HANDLE *phECDSAKey) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + /* Each magic corresponds to a different key: + * SFUM_1 = SBSFU_KEY_1 + * SFUM_2 = SBSFU_KEY_2 + * SFUM_3 = SBSFU_KEY_3 + */ + if (memcmp(pxSE_Metadata->SFUMagic, SFUM_1, strlen(SFUM_1)) == 0) + { + *phECDSAKey = KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#if (SFU_NB_MAX_ACTIVE_IMAGE > 1U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_2, strlen(SFUM_2)) == 0) + { + *phECDSAKey = KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 1) */ +#if (SFU_NB_MAX_ACTIVE_IMAGE > 2U) + else if (memcmp(pxSE_Metadata->SFUMagic, SFUM_3, strlen(SFUM_3)) == 0) + { + *phECDSAKey = KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE; + e_ret_status = SE_SUCCESS; + } +#endif /* (NB_FW_IMAGES > 2) */ + else + { + e_ret_status = SE_ERROR; + } + + return e_ret_status; +} +#endif /*((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) */ + + +/** + * @brief Secure Engine Decrypt Init function. + * It is a wrapper of Decrypt_Init function included in the protected area. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pxSE_Metadata Metadata that will be used to fill the Crypto Init structure. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_Decrypt_Init(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxSE_Metadata, uint32_t SE_FwType) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + CK_RV rv = CKR_OK; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint8_t *gcm_iv = pxSE_Metadata->Nonce; + CK_OBJECT_HANDLE hAESKey = 0UL; + + CK_GCM_PARAMS kms_test_gcm_params = + { + (CK_BYTE *)gcm_iv, + SE_NONCE_LEN, + NULL, + 0, + GCM_TAGBITS_SIZE + }; + + CK_MECHANISM cktest_aes_gcm_mechanism = + { + CKM_AES_GCM, + (CK_VOID_PTR *) &kms_test_gcm_params, + sizeof(kms_test_gcm_params) + }; + + gcm_tag_header = pxSE_Metadata->FwTag; + +#elif (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + CK_RV rv = CKR_OK; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint8_t *iv_cbc = pxSE_Metadata->InitVector; + CK_OBJECT_HANDLE hAESKey = 0UL; + + CK_MECHANISM cktest_aes_cbc_mechanism = + { + CKM_AES_CBC, + iv_cbc, + SE_IV_LEN + }; +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* + * In this crypto scheme the Firmware is not encrypted. + * The Decrypt operation is called anyhow before installing the firmware. + * Indeed, it allows moving the Firmware image blocks in FLASH. + * These moves are mandatory to create the appropriate mapping in FLASH + * allowing the swap procedure to run without using the swap area at each and every move. + * + * See in SB_SFU project: @ref SFU_IMG_PrepareCandidateImageForInstall. + */ +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Check the pointer allocation */ + if (pxSE_Metadata == NULL) + { + return SE_ERROR; + } +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + /* Initialize the KMS service */ + C_Initialize(NULL) ; + + /* Start by opening a session */ + rv = C_OpenSession(0, session_flags, NULL, 0, &DecryptSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetAESKeyObject(pxSE_Metadata, &hAESKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#endif /* (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) */ + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + if (se_status == SE_SUCCESS) + { + /* Initialize the decryption session */ + rv = C_DecryptInit(DecryptSession, &cktest_aes_gcm_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + +#elif (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + /* Initialize the decryption session */ + if (se_status == SE_SUCCESS) + { + rv = C_DecryptInit(DecryptSession, &cktest_aes_cbc_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* Nothing to do as we won't decrypt anything */ +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + return se_status; +} + +/** + * @brief Secure Engine Decrypt Append function. + * It is a wrapper of Decrypt_Append function included in the protected area. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pInputBuffer pointer to Input Buffer. + * @param uInputSize Input Size (bytes). + * @param pOutputBuffe pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_Decrypt_Append(SE_StatusTypeDef *peSE_Status, const uint8_t *pInputBuffer, int32_t InputSize, + uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + CK_RV rv = CKR_OK; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + + /* DecryptImageInDwlSlot() always starts by calling the Decrypt service with a 0 byte buffer */ + if (0 == InputSize) + { + /* Nothing to do but we must return a success for the decrypt operation to continue */ + return (SE_SUCCESS); + } + + /* Check the pointers allocation */ + if ((pInputBuffer == NULL) || (pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + /* Buffer decryption */ + rv = C_DecryptUpdate(DecryptSession, (CK_BYTE *)pInputBuffer, InputSize, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* + * The firmware is not encrypted. + * The only thing we need to do is to recopy the input buffer in the output buffer + */ + (void)memcpy(pOutputBuffer, pInputBuffer, (uint32_t)InputSize); + *pOutputSize = InputSize; + se_status = SE_SUCCESS; +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + + return se_status; +} + +/** + * @brief Secure Engine Decrypt Finish function. + * It is a wrapper of Decrypt_Finish function included in the protected area. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pOutputBuffer pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_Decrypt_Finish(SE_StatusTypeDef *peSE_Status, uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + *peSE_Status = SE_OK; + SE_ErrorStatus se_status = SE_SUCCESS; +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + CK_RV rv = CKR_OK; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + + /* Check the pointers allocation */ + if ((pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + memcpy(pOutputBuffer, gcm_tag_header, 16); + + /* End-up decryption session */ + rv = C_DecryptFinal(DecryptSession, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#elif SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + /* Nothing to do */ + se_status = SE_SUCCESS; +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 */ + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) + /* Close the session */ + rv = C_CloseSession(DecryptSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* End-up the KMS service */ + C_Finalize(NULL) ; +#endif /* (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) */ + + return se_status; +} + +/** + * @brief Secure Engine Firmware Authentication Init function. + * It is a wrapper of AuthenticateFW_Init function included in the Firewall. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pxSE_Metadata Metadata that will be used to fill the Crypto Init structure. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_AuthenticateFW_Init(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxSE_Metadata, + uint32_t SE_FwType) +{ + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_RV rv = CKR_OK; + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + uint8_t *gcm_iv = pxSE_Metadata->Nonce; + CK_OBJECT_HANDLE hAESKey; + + CK_GCM_PARAMS kms_test_gcm_params = + { + (CK_BYTE *)gcm_iv, + SE_NONCE_LEN, + NULL, + 0, + GCM_TAGBITS_SIZE + }; + + CK_MECHANISM cktest_aes_gcm_mechanism = + { + CKM_AES_GCM, + (CK_VOID_PTR *) &kms_test_gcm_params, + sizeof(kms_test_gcm_params) + }; + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + CK_MECHANISM cktest_sha_256_mechanism = + { + CKM_SHA256, + NULL, + 0 + }; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Check the pointer allocation */ + if (pxSE_Metadata == NULL) + { + return SE_ERROR; + } + + /* Initialize the KMS service */ + C_Initialize(NULL) ; + + /* Start by opening a session */ + rv = C_OpenSession(0, session_flags, NULL, 0, &AuthenticateSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetAESKeyObject(pxSE_Metadata, &hAESKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* Initialize encryption session */ + rv = C_EncryptInit(AuthenticateSession, &cktest_aes_gcm_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + /* Digest initialization */ + rv = C_DigestInit(AuthenticateSession, &cktest_sha_256_mechanism); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + return se_status; +} + +/** + * @brief Secure Engine Firmware Authentication Append function. + * It is a wrapper of AuthenticateFW_Append function included in the Firewall. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pInputBuffer pointer to Input Buffer. + * @param uInputSize Input Size (bytes). + * @param pOutputBuffer pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_AuthenticateFW_Append(SE_StatusTypeDef *peSE_Status, const uint8_t *pInputBuffer, int32_t InputSize, + uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + CK_RV rv = CKR_OK; + + /* Check the pointers allocation */ + if ((pInputBuffer == NULL) || (pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* Buffer encryption */ + rv = C_EncryptUpdate(AuthenticateSession, (CK_BYTE *)pInputBuffer, InputSize, pOutputBuffer, + (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + /* Digest calculation */ + rv = C_DigestUpdate(AuthenticateSession, (CK_BYTE_PTR)pInputBuffer, InputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + return se_status; +} + +/** + * @brief Secure Engine Firmware Authentication Finish function. + * It is a wrapper of AuthenticateFW_Finish function included in the Firewall. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pOutputBuffer pointer to Output Buffer. + * @param puOutputSize pointer to Output Size (bytes). + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_AuthenticateFW_Finish(SE_StatusTypeDef *peSE_Status, uint8_t *pOutputBuffer, int32_t *pOutputSize) +{ + SE_ErrorStatus se_status = SE_SUCCESS; + CK_RV rv = CKR_OK; + + /* Check the pointers allocation */ + if ((pOutputBuffer == NULL) || (pOutputSize == NULL)) + { + return SE_ERROR; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* End-up encryption session */ + rv = C_EncryptFinal(AuthenticateSession, pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256) ) + /* End-up Digest calculation */ + rv = C_DigestFinal(AuthenticateSession, (CK_BYTE_PTR)pOutputBuffer, (CK_ULONG_PTR)pOutputSize); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Close the session */ + rv = C_CloseSession(AuthenticateSession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* End-up the KMS service */ + C_Finalize(NULL) ; + + return se_status; +} + +/** + * @brief Secure Engine Verify Raw Fw Header Tag. + * It verifies the signature of a raw header file. + * @param peSE_Status Secure Engine Status. + * This parameter can be a value of @ref SE_Status_Structure_definition. + * @param pFwRawHeader pointer to RawHeader Buffer. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SFU_VerifyHeaderSignature(SE_StatusTypeDef *peSE_Status, SE_FwRawHeaderTypeDef *pxFwRawHeader) +{ + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_RV rv = CKR_OK; + SE_ErrorStatus se_status = SE_SUCCESS; + *peSE_Status = SE_OK; + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + int32_t fw_raw_header_output_length = SE_TAG_LEN; + uint8_t *gcm_iv = pxFwRawHeader->Nonce; + SE_FwRawHeaderTypeDef *gcm_header = pxFwRawHeader; + CK_OBJECT_HANDLE hAESKey = 0UL; + + CK_GCM_PARAMS kms_test_gcm_params = + { + (CK_BYTE *)gcm_iv, + SE_NONCE_LEN, + (CK_BYTE_PTR)gcm_header, + ((int32_t)SE_FW_AUTH_LEN), + GCM_TAGBITS_SIZE + }; + + CK_MECHANISM cktest_aes_gcm_mechanism = + { + CKM_AES_GCM, + (CK_VOID_PTR *) &kms_test_gcm_params, + sizeof(kms_test_gcm_params) + }; + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) + + const uint8_t *pPayload; /* Metadata payload */ + int32_t payloadSize; /* Metadata length to be considered for hash */ + uint8_t *pSignature = pxFwRawHeader->HeaderSignature; /* Signature ECDSA */ + CK_OBJECT_HANDLE hECDSAKey = 0UL; + CK_MECHANISM cktest_ecdsa_256_mechanism = + { + CKM_ECDSA_SHA256, + NULL, + 0 + }; +#endif /* SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM */ + + /* Check the pointers allocation */ + if (NULL == pxFwRawHeader) + { + *peSE_Status = SE_KO; + return SE_ERROR; + } + +#if ((SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)) + gcm_tag_header = pxFwRawHeader->HeaderSignature; +#endif /* SECBOOT_CRYPTO_SCHEME */ + + + /* Initialize the KMS service */ + C_Initialize(NULL) ; + + /* Start by opening a session */ + rv = C_OpenSession(0, session_flags, NULL, 0, &VerifySession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#if (SECBOOT_CRYPTO_SCHEME == SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM) + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetAESKeyObject(pxFwRawHeader, &hAESKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* Initialize the decryption session */ + rv = C_DecryptInit(VerifySession, &cktest_aes_gcm_mechanism, hAESKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + + /* End-up decryption session : control if the tag is correct */ + rv = C_DecryptFinal(VerifySession, gcm_tag_header, (CK_ULONG_PTR)&fw_raw_header_output_length); + + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + +#elif ((SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256)\ + || (SECBOOT_CRYPTO_SCHEME == SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256)) + + pPayload = (const uint8_t *)pxFwRawHeader; + payloadSize = SE_FW_AUTH_LEN; /* Authenticated part of the header */ + + /* Identify the keys after FW header analysis (magic tag) */ + if (SFU_GetECDSAKeyObject(pxFwRawHeader, &hECDSAKey) != SE_SUCCESS) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* Initialize the verification process */ + rv = C_VerifyInit(VerifySession, &cktest_ecdsa_256_mechanism, hECDSAKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + + /* End-up verification process : control if the signature is correct */ + rv = C_Verify(VerifySession, (CK_BYTE_PTR)pPayload, payloadSize, (CK_BYTE_PTR)pSignature, SE_HEADER_SIGN_LEN); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* Double Check to avoid basic fault injection */ + if (se_status == SE_SUCCESS) + { + /* Initialize the verification process */ + rv = C_VerifyInit(VerifySession, &cktest_ecdsa_256_mechanism, hECDSAKey); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + if (se_status == SE_SUCCESS) + { + /* End-up verification process : control if the signature is correct */ + rv = C_Verify(VerifySession, (CK_BYTE_PTR)pPayload, payloadSize, (CK_BYTE_PTR)pSignature, SE_HEADER_SIGN_LEN); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + } + } + +#else +#error "The current example does not support the selected crypto scheme." +#endif /* SECBOOT_CRYPTO_SCHEME */ + + /* Close the session */ + rv = C_CloseSession(VerifySession); + if (rv != CKR_OK) + { + se_status = SE_ERROR; + *peSE_Status = SE_KO; + } + + /* End-up the KMS service */ + C_Finalize(NULL) ; + + return se_status; + +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_interface_crypto_scheme.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_interface_crypto_scheme.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_kms.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_kms.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_kms.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_kms.c diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_kms.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_kms.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_kms.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_kms.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_loader.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_loader.c new file mode 100644 index 00000000..30a80b45 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_loader.c @@ -0,0 +1,785 @@ +/** + ****************************************************************************** + * @file sfu_loader.c + * @author MCD Application Team + * @brief Secure Firmware Update LOADER module. + * This file provides set of firmware functions to manage SFU local + * loader functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "main.h" +#include "sfu_loader.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "sfu_com_loader.h" +#include "sfu_trace.h" +#include "se_interface_bootloader.h" /* for metadata authentication */ +#include "sfu_interface_crypto_scheme.h" +#include "sfu_fwimg_services.h" /* for version checking & to check if a valid FW is installed (the local + bootloader is a kind of "application" running in SB_SFU) */ +#include "app_sfu.h" + +#if (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) + +/* Private variables ---------------------------------------------------------*/ +#ifdef MINICOM_YMODEM +/* + * With Minicom Ymodem, the data offset is not aligned because SFU_COM_YMODEM_PACKET_DATA_INDEX is 7 + * So we cannot write in FLASH with p_data as source, we need a copy in an aligned buffer + */ +/* With Minicom YMODEM each packet carries 128 bytes of data */ +static uint8_t alignedBuffer[SFU_COM_YMODEM_PACKET_SIZE] __attribute__((aligned(8))); +#endif /* MINICOM_YMODEM */ +static uint32_t m_uDwlAreaAddress = 0U; /*!< Address of to write in download area */ +static uint32_t m_uDwlAreaStart = 0U; /*!< Address of download area */ +static uint32_t m_uDwlAreaSize = 0U; /*!< Size of download area */ +static uint32_t m_uFileSizeYmodem = 0U; /*!< Ymodem file size being received */ +static uint32_t m_uNbrBlocksYmodem = 0U; /*!< Number of blocks being received via Ymodem*/ +static uint32_t m_uPacketsReceived = 0U; /*!< Number of packets received via Ymodem*/ +static uint32_t m_uDwlSlot = SLOT_INACTIVE; /*!< Dwl slot identification : to be intialialized after header check */ +static SFU_LOADER_StatusTypeDef m_LoaderStatus; /*!< Status of the loader */ + +/* Private function prototypes -----------------------------------------------*/ +static SFU_ErrorStatus SFU_LOADER_VerifyFwHeader(uint8_t *pBuffer); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Initialize the SFU LOADER. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LOADER_Init(void) +{ + /* + * ADD SRC CODE HERE + */ + + /* + * Sanity check to make sure that the local loader cannot read out of the buffer bounds + * when doing a length alignment before writing in FLASH. + */ +#ifndef MINICOM_YMODEM + /* m_aPacketData contains SFU_COM_YMODEM_PACKET_1K_SIZE bytes of payload */ + if (0U != (uint32_t)(SFU_COM_YMODEM_PACKET_1K_SIZE % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + /* The packet buffer (payload part) must be a multiple of the FLASH write length */ + TRACE("\r\n= [FWIMG] Packet Payload size (%d) is not matching the FLASH constraints", + SFU_COM_YMODEM_PACKET_1K_SIZE); + return SFU_ERROR; + } /* else the FW Header Length is fine with regards to FLASH constraints */ +#else /* MINICOM_YMODEM */ + /* m_aPacketData contains SFU_COM_YMODEM_PACKET_SIZE bytes of payload */ + if (0U != (uint32_t)(SFU_COM_YMODEM_PACKET_SIZE % (uint32_t)sizeof(SFU_LL_FLASH_write_t))) + { + /* The packet buffer (payload part) must be a multiple of the FLASH write length */ + TRACE("\r\n= [FWIMG] Packet Payload size (%d) is not matching the FLASH constraints", SFU_COM_YMODEM_PACKET_SIZE); + return SFU_ERROR; + } +#endif /* MINICOM_YMODEM */ + + return SFU_SUCCESS; +} + +/** + * @brief DeInitialize the SFU LOADER. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LOADER_DeInit(void) +{ + /* + * ADD SRC CODE HERE + */ + return SFU_SUCCESS; +} + +/** + * @brief Download a new User Fw. + * Writes firmware received via Ymodem in FLASH. + * @param peSFU_LOADER_Status: SFU LOADER Status. + * This parameter can be a value of @ref SFU_LOADER_Status_Structure_definition. + * @param p_DwlSlot identification of the downloaded area + * @param p_Size Size of the downloaded image. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LOADER_DownloadNewUserFw(SFU_LOADER_StatusTypeDef *peSFU_LOADER_Status, uint32_t *pDwlSlot, + uint32_t *pSize) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SFU_COM_YMODEM_StatusTypeDef e_com_status = SFU_COM_YMODEM_ERROR; + + /* Check the pointers allocation */ + if ((peSFU_LOADER_Status == NULL) || (pSize == NULL) || (pDwlSlot == NULL)) + { + return SFU_ERROR; + } + + /* Refresh Watchdog */ + (void) SFU_LL_SECU_IWDG_Refresh(); + + /* Transfer FW Image via YMODEM protocol */ + TRACE("\r\n\t File> Transfer> YMODEM> Send "); + + /* Initialize global variables to be used during the YMODEM process */ + m_uDwlAreaAddress = 0U; + m_uDwlAreaStart = 0U; + m_uDwlAreaSize = 0U; + m_uFileSizeYmodem = 0U; + m_uNbrBlocksYmodem = 0U; + m_uPacketsReceived = 0U; + m_uDwlSlot = SLOT_DWL_1; + m_LoaderStatus = SFU_LOADER_ERR_COM; + + /* Receive the FW in RAM and write it in the Flash*/ + if (SFU_COM_YMODEM_Receive(&e_com_status, pSize) == SFU_SUCCESS) + { + if (*pSize > 0U) + { + /* File download correct*/ + m_LoaderStatus = SFU_LOADER_OK; + } + } + else + { + /* Nothing to do : m_LoaderStatus updated during during YModem process */ + } + + /* Provide slot information to the caller + m_uDwlSlot updated during VerifyFwHeader() except in case of bad formatted file + ==> m_uDwlSlot stick at SLOT_DWL_1 value if the header signature is not verified */ + *pDwlSlot = m_uDwlSlot; + + + *peSFU_LOADER_Status = m_LoaderStatus; + if (m_LoaderStatus == SFU_LOADER_OK) + { + e_ret_status = SFU_SUCCESS; + } + return e_ret_status; +} + +/** + * @brief Ymodem Header Packet Transfer completed callback. + * @param uFileSize: Dimension of the file that will be received. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_COM_YMODEM_HeaderPktRxCpltCallback(uint32_t uFileSize) +{ + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + + /*Filesize information is stored*/ + m_uFileSizeYmodem = uFileSize; + + /*Compute the number of blocks */ +#ifndef MINICOM_YMODEM + /* Teraterm sends 1kB YMODEM packets */ + m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (SFU_COM_YMODEM_PACKET_1K_SIZE - 1U)) / SFU_COM_YMODEM_PACKET_1K_SIZE; +#else + /* Minicom sends 128 bytes YMODEM packets */ + m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (SFU_COM_YMODEM_PACKET_SIZE - 1U)) / SFU_COM_YMODEM_PACKET_SIZE; +#endif /* MINICOM_YMODEM */ + + /* NOTE : delay inserted for Ymodem protocol*/ + HAL_Delay(1000U); + + return SFU_SUCCESS; +} + +/** + * @brief Ymodem Data Packet Transfer completed callback. + * @param pData: Pointer to the buffer. + * @param uSize: Packet dimension. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +#ifndef MINICOM_YMODEM +/* Teraterm variant of the YMODEM protocol: uses 1kB packets */ +SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) +{ + /* The local loader must make a copy of the Firmware metadata, + * because this memory area is not copied when calling the SE_Decrypt_Init() primitive. + * Hence we must make sure this memory area still contains the FW header when SE_Decrypt_Finish() is called. */ + static uint8_t fw_header[SE_FW_HEADER_TOT_LEN] __attribute__((aligned(8))); + /* Size of downloaded Image initialized with first packet (header) and checked along download process */ + static uint32_t m_uDwlImgSize = 0U; + + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + SFU_FLASH_StatusTypeDef x_flash_info; + uint32_t rx_size = uSize; + uint8_t *p_data = pData; + uint32_t uOldSize; +#if !defined(SFU_NO_SWAP) + uint32_t uLength; +#endif /* !SFU_NO_SWAP */ + + /* Check the pointers allocation */ + if (p_data == NULL) + { + return SFU_ERROR; + } + + /*Increase the number of received packets*/ + m_uPacketsReceived++; + + /* Last packet : size of data to write could be different than SFU_COM_YMODEM_PACKET_1K_SIZE */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + /*Extracting actual payload from last packet*/ + if (0U == (m_uFileSizeYmodem % SFU_COM_YMODEM_PACKET_1K_SIZE)) + { + /* The last packet must be fully considered */ + rx_size = SFU_COM_YMODEM_PACKET_1K_SIZE; + } + else + { + /* The last packet is not full, drop the extra bytes */ + rx_size = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / SFU_COM_YMODEM_PACKET_1K_SIZE) * + SFU_COM_YMODEM_PACKET_1K_SIZE); + } + } + + /* First packet : Contains the FW header (SE_FW_HEADER_TOT_LEN bytes length) which is not encrypted */ + if (m_uPacketsReceived == 1U) + { + + (void) memcpy(fw_header, p_data, SE_FW_HEADER_TOT_LEN); + + /* Verify header */ + e_ret_status = SFU_LOADER_VerifyFwHeader(p_data); + if (e_ret_status == SFU_SUCCESS) + { + m_uDwlAreaAddress = m_uDwlAreaStart; +#if defined(SFU_NO_SWAP) + + /* Downloaded Image size : Header size + Image size */ + m_uDwlImgSize = ((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header)->FwSize + SFU_IMG_IMAGE_OFFSET; +#else + /* Downloaded Image size : Header size + gap for image alignment to (UpdateFwOffset % sector size) + + Partial Image size */ + m_uDwlImgSize = ((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header)->PartialFwSize + + (((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header)->PartialFwOffset % SLOT_SIZE(SLOT_SWAP)) + + SFU_IMG_IMAGE_OFFSET; +#endif /* (SFU_NO_SWAP) */ + } + + /* Clear Download application area (including TRAILERS area) */ + if (e_ret_status == SFU_SUCCESS) + { + if (SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) m_uDwlAreaAddress, SLOT_SIZE(m_uDwlSlot)) != + SFU_SUCCESS) + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + + } + +#if !defined(SFU_NO_SWAP) + if (e_ret_status == SFU_SUCCESS) + { + /* This packet : contains end of FW header */ + if ((m_uDwlAreaAddress < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) && + ((m_uDwlAreaAddress + rx_size) >= (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET))) + { + /* Write the FW header part (SFU_IMG_IMAGE_OFFSET % SFU_COM_YMODEM_PACKET_1K_SIZE bytes length) */ + uLength = SFU_IMG_IMAGE_OFFSET % SFU_COM_YMODEM_PACKET_1K_SIZE; + if (uLength == 0U) + { + uLength = SFU_COM_YMODEM_PACKET_1K_SIZE; + } + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, p_data, uLength) == SFU_SUCCESS) + { + /* Shift the DWL area pointer, to align image with (PartialFwOffset % sector size) in DWL area */ + m_uDwlAreaAddress += uLength + (((SE_FwRawHeaderTypeDef *)(uint32_t)fw_header)->PartialFwOffset % + SLOT_SIZE(SLOT_SWAP)); + + /* Update remaining packet size to write */ + rx_size -= uLength; + + /* Update p_data pointer to received packet data */ + p_data += uLength; + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + } +#endif /* !SFU_NO_SWAP */ + + if (e_ret_status == SFU_SUCCESS) + { + /* Check size to avoid writing beyond DWL image size */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlImgSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Set dimension to the appropriate length for FLASH programming. + * Example: 64-bit length for L4. + */ + if ((rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t)) != 0U) + { + /* By construction, the length of the buffer (fw_decrypted_chunk or p_data) must be a multiple of + sizeof(SFU_IMG_write_t) to avoid reading out of the buffer */ + uOldSize = rx_size; + rx_size = rx_size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - (rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); + while (uOldSize < rx_size) + { + p_data[uOldSize] = 0xFF; + uOldSize++; + } + } + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Check size to avoid writing beyond DWL area */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlAreaSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + } + + /* Write Data in Flash */ + if (e_ret_status == SFU_SUCCESS) + { + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, p_data, rx_size) == SFU_SUCCESS) + { + m_uDwlAreaAddress += (rx_size); + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + + + /* Last packet : reset m_uPacketsReceived */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + m_uPacketsReceived = 0U; + } + + /* Reset data counters in case of error */ + if (e_ret_status == SFU_ERROR) + { + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + } + + return e_ret_status; +} +#else /* MINICOM_YMODEM */ +/* Minicom variant of the YMODEM protocol: uses 128B packets */ +SFU_ErrorStatus SFU_COM_YMODEM_DataPktRxCpltCallback(uint8_t *pData, uint32_t uSize) +{ + /* The local loader must make a copy of the Firmware metadata, + * because this memory area is not copied when calling the SE_Decrypt_Init() primitive. + * Hence we must make sure this memory area still contains the FW header when SE_Decrypt_Finish() is called. */ + static uint8_t fw_header[SE_FW_HEADER_TOT_LEN] __attribute__((aligned(8))); + /* Size of downloaded Image initialized with first packet (header) and checked along download process */ + static uint32_t m_uDwlImgSize = 0U; + + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + SFU_FLASH_StatusTypeDef x_flash_info; + uint32_t rx_size = uSize; + uint8_t *p_data = pData; + uint32_t uOldSize; + + /* Check the pointers allocation */ + if (p_data == NULL) + { + return SFU_ERROR; + } + + /*Increase the number of received packets*/ + m_uPacketsReceived++; + + /* Last packet : size of data to write could be different than SFU_COM_YMODEM_PACKET_1K_SIZE */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + /*Extracting actual payload from last packet: minicom works by default with 128B packets */ + if (0 == (m_uFileSizeYmodem % SFU_COM_YMODEM_PACKET_SIZE)) + { + /* The last packet must be fully considered */ + rx_size = SFU_COM_YMODEM_PACKET_SIZE; + } + else + { + /* The last packet is not full, drop the extra bytes: minicom works by default with 128B packets */ + rx_size = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / SFU_COM_YMODEM_PACKET_SIZE) * + SFU_COM_YMODEM_PACKET_SIZE); + } + } + + + /* + * Minicom splits the header of 192 bytes on 2 packets of 128 bytes. + */ + + /* First packet : Contains the first 128B of FW header (out of SE_FW_HEADER_TOT_LEN bytes length) which is + not encrypted */ + if (1 == m_uPacketsReceived) + { + /* First packet: beginning of header */ + if (SFU_COM_YMODEM_PACKET_SIZE == rx_size) + { + /* Copy the beginning of the header */ + memcpy(fw_header, p_data, rx_size); + rx_size = 0U; /* nothing more to do */ + } + else + { + /* Unexpected case */ + e_ret_status = SFU_ERROR; + } + } + else if (2U == m_uPacketsReceived) + { + /* Second packet: end of header (64 bytes) */ + memcpy(fw_header + SFU_COM_YMODEM_PACKET_SIZE, p_data, 64U); + rx_size -= 64U; + p_data += 64U; + + /* Verify header */ + e_ret_status = SFU_LOADER_VerifyFwHeader(fw_header); + + if (e_ret_status == SFU_SUCCESS) + { + m_uDwlAreaAddress = m_uDwlAreaStart; + /* Downloaded Image size : Header size + gap for image alignment to (UpdateFwOffset % sector size) + + Partial Image size */ + m_uDwlImgSize = ((SE_FwRawHeaderTypeDef *)fw_header)->PartialFwSize + + (((SE_FwRawHeaderTypeDef *)fw_header)->PartialFwOffset % SLOT_SIZE(SLOT_SWAP)) + + SFU_IMG_IMAGE_OFFSET; + + /* Clear Download application area (including TRAILERS area) */ + if ((e_ret_status == SFU_SUCCESS) + && (SFU_LL_FLASH_Erase_Size(&x_flash_info, (uint8_t *) m_uDwlAreaAddress, SLOT_SIZE(m_uDwlSlot)) != + SFU_SUCCESS)) + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + + if (e_ret_status == SFU_SUCCESS) + { + /* Write the FW header (SE_FW_HEADER_TOT_LEN bytes length) at start of DWL area */ + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, fw_header, SE_FW_HEADER_TOT_LEN) + == SFU_SUCCESS) + { + /* Shift the DWL area pointer (still to be aligned image with (PartialFwOffset % sector size) in DWL area ) */ + m_uDwlAreaAddress += SE_FW_HEADER_TOT_LEN; + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + /* The remaining 64 bytes of data must be handled : standard processing */ + } + } + /* + * Else: standard packet data processing based on rx_size (full packet or the last 64 bytes of the 2nd packet) + */ + if (e_ret_status == SFU_SUCCESS) + { + /* + * End of the second packet (64B) or full 128B packet + * Skip padding bytes then take partial FW offset into account + */ + if (m_uDwlAreaAddress < (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET)) + { + /* Skip the padding bytes */ + m_uDwlAreaAddress += rx_size; + rx_size = 0U; + } + else + { + /* + * m_uDwlAreaAddress >= (m_uDwlAreaStart + SFU_IMG_IMAGE_OFFSET) + */ + if (((SFU_IMG_IMAGE_OFFSET / SFU_COM_YMODEM_PACKET_SIZE) + 1) == m_uPacketsReceived) + { + /* End of padding bytes : We must take the partial offset into account */ + m_uDwlAreaAddress += ((SE_FwRawHeaderTypeDef *)fw_header)->PartialFwOffset % SLOT_SIZE(SLOT_SWAP); + } + /* else nothing more to do */ + + /* Check size to avoid writing beyond DWL image size */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlImgSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + + /* + * Set dimension to the appropriate length for FLASH programming. + * Example: 64-bit length for L4. + */ + if ((rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t)) != 0) + { + /* + * By construction, the length of the buffer (fw_decrypted_chunk or p_data) must be a multiple of + * sizeof(SFU_IMG_write_t) to avoid reading out of the buffer + */ + uOldSize = rx_size; + rx_size = rx_size + ((uint32_t)sizeof(SFU_LL_FLASH_write_t) - + (rx_size % (uint32_t)sizeof(SFU_LL_FLASH_write_t))); + while (uOldSize < rx_size) + { + p_data[uOldSize] = 0xFF; + uOldSize++; + } + } + + /* Check size to avoid writing beyond DWL area */ + if ((m_uDwlAreaAddress + rx_size) > (m_uDwlAreaStart + m_uDwlAreaSize)) + { + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + e_ret_status = SFU_ERROR; + } + + /* Write Data in Flash */ + if (e_ret_status == SFU_SUCCESS) + { + /* + * With Minicom Ymodem, the data offset is not aligned because SFU_COM_YMODEM_PACKET_DATA_INDEX is 7 + * So we cannot write in FLASH with p_data as source, we need a copy in an aligned buffer + */ + memcpy(alignedBuffer, p_data, rx_size); + + if (SFU_LL_FLASH_Write(&x_flash_info, (uint8_t *)m_uDwlAreaAddress, alignedBuffer, rx_size) == SFU_SUCCESS) + { + m_uDwlAreaAddress += (rx_size); + } + else + { + m_LoaderStatus = SFU_LOADER_ERR_FLASH; + e_ret_status = SFU_ERROR; + } + } + } + } + + + /* Last packet : reset m_uPacketsReceived */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + m_uPacketsReceived = 0U; + } + + /* Reset data counters in case of error */ + if (e_ret_status == SFU_ERROR) + { + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + } + + return e_ret_status; +} +#endif /* MINICOM_YMODEM */ + + +/** + * @brief Verifies the Raw Fw Header received. It checks if the header is + * authentic and if the fields are ok with the device (e.g. size and version). + * @note Please note that when the new image is installed, this metadata is checked + * by @ref SFU_IMG_CheckCandidateVersion. + * @param peSFU_LOADER_Status: SFU LOADER Status. + * This parameter can be a value of @ref SFU_LOADER_Status_Structure_definition. + * @param pBuffer: pointer to header Buffer. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ + +/* anti-rollback mechanism is tested twice to avoid basic hardware attack + ==> compiler optimization is disabled for this reason */ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O0"))) +#endif /* __ICCARM__ */ + +static SFU_ErrorStatus SFU_LOADER_VerifyFwHeader(uint8_t *pBuffer) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_StatusTypeDef e_se_status; + SE_FwRawHeaderTypeDef *p_x_fw_raw_header; + SFU_FwImageFlashTypeDef fw_image_flash_data; + uint16_t cur_ver; + uint16_t verif_ver; + uint32_t active_slot; + + /*Parse the received buffer*/ + p_x_fw_raw_header = (SE_FwRawHeaderTypeDef *)(uint32_t)pBuffer; + /*Check if the received header packet is authentic*/ + if (SE_VerifyHeaderSignature(&e_se_status, p_x_fw_raw_header) != SE_ERROR) + { + active_slot = SFU_IMG_GetFwImageSlot(p_x_fw_raw_header); + /* + * 2 slots per image configuration. Identify the download area. + * It will be based on SFU magic : + * - same number as active_slot if configured. + * - else : SLOT_DWL_1 + * As example : Header magic is SFU2, active slot is SLOT_ACTIVE_2 and dwl slot will be SLOT_DWL2. + */ + m_uDwlSlot = active_slot - SLOT_ACTIVE_1 + SLOT_DWL_1; + if (SLOT_SIZE(m_uDwlSlot) == 1U) + { + m_uDwlSlot = SLOT_DWL_1; + } + SFU_IMG_GetDownloadAreaInfo(m_uDwlSlot, &fw_image_flash_data); + + /* Assign the download flash address to be used during the YMODEM process */ + m_uDwlAreaStart = fw_image_flash_data.DownloadAddr; + m_uDwlAreaSize = fw_image_flash_data.MaxSizeInBytes; + + /* + * Check if the version is allowed + * ==> SFU_IMG_GetActiveFwVersion() returns 0 if the header of active firmware is not valid + */ + cur_ver = SFU_IMG_GetActiveFwVersion(active_slot); + if (SFU_IMG_CheckFwVersion(active_slot, cur_ver, p_x_fw_raw_header->FwVersion) == SFU_SUCCESS) + { +#if defined(SFU_NO_SWAP) + /* + * Check length : Let's make sure the Firmware image can be written in the destination slot. + */ + if (p_x_fw_raw_header->FwSize > (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) +#else + /* + * Check length : + * We do not check the length versus the trailer constraint because this check is already implemented in + * FirmwareToInstall(). + * If the firmware is too big to have some room left for the trailer info then the installation will not be + * triggered. + * The interest is to avoid duplicating the checks (checking just in time). + * This is also because in the case of a download handled by the UserApp we cannot rely on the checks done + * by the UserApp before installing a FW. + * The drawback is that the firmware can be downloaded in dwl slot though it is too big. + * + * Nevertheless, we can still detect if the FW is too big to be downloaded (cannot be written in dwl slot). + * This will avoid download issues (but the installation itself can still be rejected) or overflows. + * The dwl slot must contain the HEADER and also the binary FW (encrypted). + * But there is an offset of FW_OFFSET_IMAGE bytes to respect. + */ + if ((p_x_fw_raw_header->PartialFwSize + (p_x_fw_raw_header->PartialFwOffset % SLOT_SIZE(SLOT_SWAP))) > + (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) +#endif /* SFU_NO_SWAP */ + { + /* The firmware cannot be written in dwl slot */ + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + } + else + { + /* Installation authorized */ + e_ret_status = SFU_SUCCESS; + } + } + else + { + /* The installation is forbidden */ + TRACE("\r\n Anti-rollback: candidate version(%d) rejected | current version(%d) , min.version(%d) !", + p_x_fw_raw_header->FwVersion, cur_ver, SFU_FW_VERSION_START_NUM); + m_LoaderStatus = SFU_LOADER_ERR_FW_VERSION; + } + + + /* + * Control of version and length is done twice to avoid basic hardware attack + * This more important for the 1 image configuration as the installation is done during the download procedure + * For the 2 images configuration anti-rollback will be checked again during installation process + */ + verif_ver = SFU_IMG_GetActiveFwVersion(active_slot); + if (SFU_IMG_CheckFwVersion(active_slot, verif_ver, p_x_fw_raw_header->FwVersion) == SFU_SUCCESS) + { +#if defined(SFU_NO_SWAP) + /* + * Check length : Let's make sure the Firmware image can be written in the destination slot. + */ + if (p_x_fw_raw_header->FwSize > (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) +#else + /* + * Check length : + * We do not check the length versus the trailer constraint because this check is already implemented in + * FirmwareToInstall(). + * If the firmware is too big to have some room left for the trailer info then the installation will not be + * triggered. + * The interest is to avoid duplicating the checks (checking just in time). + * This is also because in the case of a download handled by the UserApp we cannot rely on the checks done + * by the UserApp before installing a FW. + * The drawback is that the firmware can be downloaded in dwl slot though it is too big. + * + * Nevertheless, we can still detect if the FW is too big to be downloaded (cannot be written in dwl slot). + * This will avoid download issues (but the installation itself can still be rejected) or overflows. + * The dwl slot must contain the HEADER and also the binary FW (encrypted). + * But there is an offset of FW_OFFSET_IMAGE bytes to respect. + */ + if ((p_x_fw_raw_header->PartialFwSize + (p_x_fw_raw_header->PartialFwOffset % SLOT_SIZE(SLOT_SWAP))) > + (SLOT_SIZE(m_uDwlSlot) - SFU_IMG_IMAGE_OFFSET)) +#endif /* SFU_NO_SWAP */ + { + /* The firmware cannot be written in dwl slot */ + m_LoaderStatus = SFU_LOADER_ERR_FW_LENGTH; + } + else + { + /* Installation authorized */ + e_ret_status = SFU_SUCCESS; + } + } + else + { + /* The installation is forbidden */ + TRACE("\r\n Anti-rollback: candidate version(%d) rejected | current version(%d) , min.version(%d) !", + p_x_fw_raw_header->FwVersion, verif_ver, SFU_FW_VERSION_START_NUM); + m_LoaderStatus = SFU_LOADER_ERR_FW_VERSION; + } + } + else + { + /* Header authentication failure */ + m_LoaderStatus = SFU_LOADER_ERR_AUTH_FAILED; + } + + return e_ret_status; +} + +#endif /* (SECBOOT_LOADER == SECBOOT_USE_LOCAL_LOADER) */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_loader.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_loader.h new file mode 100644 index 00000000..7467d978 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_loader.h @@ -0,0 +1,63 @@ +/** + ****************************************************************************** + * @file sfu_loader.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update local + * loader. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOADER_H +#define SFU_LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "se_def.h" +#include "sfu_def.h" +#include "sfu_new_image.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * Local loader status Type Definition + */ +typedef enum +{ + SFU_LOADER_OK = 0x00U, + SFU_LOADER_ERR_COM = 0x01U, + SFU_LOADER_ERR_AUTH_FAILED = 0x02U, + SFU_LOADER_ERR_FW_LENGTH = 0x03U, + SFU_LOADER_ERR_FW_VERSION = 0x04U, + SFU_LOADER_ERR_FLASH = 0x05U, + SFU_LOADER_ERR_CRYPTO = 0x06U +} SFU_LOADER_StatusTypeDef; + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LOADER_Init(void); +SFU_ErrorStatus SFU_LOADER_DeInit(void); +SFU_ErrorStatus SFU_LOADER_DownloadNewUserFw(SFU_LOADER_StatusTypeDef *peSFU_LOADER_Status, uint32_t *p_DwlSlot, + uint32_t *p_Size); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOADER_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_new_image.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_new_image.c new file mode 100644 index 00000000..8588f3a5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_new_image.c @@ -0,0 +1,98 @@ +/** + ****************************************************************************** + * @file sfu_new_image.c + * @author MCD Application Team + * @brief This file provides set of firmware functions to manage the New Firmware Image storage and installation. + * This file contains the services the bootloader can use to + * know where to store a new FW image and request its installation. + * The same services are offered to the user application thanks to a similar file integrated in the user + * application. + * @note This file is compiled in the scope of SB_SFU. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_def.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_new_image.h" +#include "sfu_fwimg_services.h" +#include "sfu_fwimg_regions.h" +#include "se_def_metadata.h" +#include /* needed for memset (see WriteInstallHeader)*/ + +#if !defined(SFU_NO_SWAP) +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Write the header of the firmware to install + * @param pfw_header pointer to header to write. + * @retval SFU_SUCCESS on success otherwise SFU_ERROR + */ +static SFU_ErrorStatus WriteInstallHeader(uint8_t *pfw_header) +{ + SFU_ErrorStatus ret = SFU_ERROR; + SFU_FLASH_StatusTypeDef flash_if_info; + + ret = SFU_LL_FLASH_Erase_Size(&flash_if_info, (uint8_t *) SlotStartAdd[SLOT_SWAP], SFU_IMG_IMAGE_OFFSET); + if (ret == SFU_SUCCESS) + { + ret = SFU_LL_FLASH_Write(&flash_if_info, (uint8_t *)SlotStartAdd[SLOT_SWAP], pfw_header, SE_FW_HEADER_TOT_LEN); + } + return ret; +} +#endif /* !SFU_NO_SWAP*/ + +/** + * @brief Write in Flash the next header image to install. + * This function is used by the local loader to request a Firmware installation (at next reboot). + * @param fw_header FW header of the FW to be installed + * @retval SFU_SUCCESS if successful, otherwise SFU_ERROR + */ +SFU_ErrorStatus SFU_IMG_InstallAtNextReset(uint8_t *fw_header) +{ +#if !defined(SFU_NO_SWAP) + if (fw_header == NULL) + { + return SFU_ERROR; + } + if (WriteInstallHeader(fw_header) != SFU_SUCCESS) + { + return SFU_ERROR; + } + return SFU_SUCCESS; +#else + return SFU_SUCCESS; /* Nothing to do */ +#endif /* !SFU_NO_SWAP*/ +} + +/** + * @brief Provide the area descriptor to write a FW image in Flash. + * This function is used by the local loader to know where to store a new Firmware Image before asking for its + * installation. + * @param DwlSlot identification of the downloaded area + * @param pArea pointer to area descriptor + * @retval none + */ +void SFU_IMG_GetDownloadAreaInfo(uint32_t DwlSlot, SFU_FwImageFlashTypeDef *pArea) +{ + pArea->DownloadAddr = SlotStartAdd[DwlSlot]; +#if !defined(SFU_NO_SWAP) + pArea->MaxSizeInBytes = (uint32_t)SLOT_SIZE(DwlSlot) - SFU_IMG_GetTrailerSize(DwlSlot); +#else + pArea->MaxSizeInBytes = (uint32_t)SLOT_SIZE(DwlSlot); +#endif /* !(SFU_NO_SWAP) */ + pArea->ImageOffsetInBytes = SFU_IMG_IMAGE_OFFSET; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM4/Inc/sfu_new_image.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_new_image.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM4/Inc/sfu_new_image.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_new_image.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_test.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_test.c new file mode 100644 index 00000000..948269d2 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_test.c @@ -0,0 +1,336 @@ +/** + ****************************************************************************** + * @file sfu_test.c + * @author MCD Application Team + * @brief Test Protections module. + * This file provides set of firmware functions to manage Test Protections + * functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_test.h" +#include "main.h" +#include "sfu_trace.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "sfu_low_level.h" +#include "string.h" /* required for strncmp */ + +#if defined(SFU_TEST_PROTECTION) + +extern RTC_HandleTypeDef RtcHandle; + +/* Private defines -----------------------------------------------------------*/ + +/* Automatic tests : list of tests (Address, Message, Operation */ +/* Flash programming by 64 bits */ +#define SHIFT_FLASH_WRITE (8U-1U) + +/* Private variables ---------------------------------------------------------*/ +static ProtectionTest_t aProtectTests[] = +{ +#ifdef SFU_MPU_PROTECT_ENABLE + {SFU_RAM_BASE, "MPU SRAM1 start add", TEST_EXECUTE}, + {SFU_RAM_END - 3U, "MPU SRAM1 end add", TEST_EXECUTE}, /* -3 : previous 32 bits for execute test */ + {PERIPH_BASE, "Peripheral base add", TEST_EXECUTE}, + {((uint32_t)0x5FFFFFFF - 3U), "Peripheral end address", TEST_EXECUTE}, /* -3 : previous 32 bits for execute test */ + /* READ_FLASH is possible as we are privileged when there is no MPU isolation but WRITE_FLASH must fail */ + {INTVECT_START, "Init. Vector", TEST_WRITE_FLASH}, + {SLOT_DWL_1_START, "MPU code dwl slot1 begin add", TEST_EXECUTE}, + {SLOT_DWL_1_END - 3U, "MPU code dwl slot1 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SLOT_DWL_2_START, "MPU code dwl slot2 begin add", TEST_EXECUTE}, + {SLOT_DWL_2_END - 3U, "MPU code dwl slot2 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SLOT_DWL_3_START, "MPU code dwl slot3 begin add", TEST_EXECUTE}, + {SLOT_DWL_3_END - 3U, "MPU code dwl slot3 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SWAP_START, "MPU code swap begin add", TEST_EXECUTE}, + {SWAP_END - 3U, "MPU code swap end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SLOT_ACTIVE_1_START, "MPU code active slot1 begin add", TEST_EXECUTE}, + {SLOT_ACTIVE_1_END - 3U, "MPU code active1 slot end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SLOT_ACTIVE_2_START, "MPU code active slot2 begin add", TEST_EXECUTE}, + {SLOT_ACTIVE_2_END - 3U, "MPU code active slot2 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SLOT_ACTIVE_3_START, "MPU code active slot3 begin add", TEST_EXECUTE}, + {SLOT_ACTIVE_3_END - 3U, "MPU code active slot3 end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ +#endif /* SFU_MPU_PROTECT_ENABLE */ +#ifdef SFU_WRP_PROTECT_ENABLE + {INTVECT_START, "WRP start add", TEST_WRITE_FLASH}, + {SFU_ROM_ADDR_END - SHIFT_FLASH_WRITE, "WRP end add", TEST_WRITE_FLASH}, /* -7 : alignment for 64bits writing test */ + {SB_REGION_ROM_START, "WRP internal (SB) add", TEST_ERASE_FLASH}, +#endif /* SFU_WRP_PROTECT_ENABLE */ +#ifdef SFU_PCROP_PROTECT_ENABLE + {SE_KEY_REGION_ROM_START, "PCROP start add", TEST_WRITE_FLASH}, + {SE_KEY_REGION_ROM_END - SHIFT_FLASH_WRITE, "PCROP end add", TEST_WRITE_FLASH}, /* -7 : alignment for 64bits + writing test */ + {SE_KEY_REGION_ROM_START, "PCROP start add", TEST_READ_FLASH}, + {SE_KEY_REGION_ROM_END, "PCROP end add", TEST_READ_FLASH}, +#endif /* SFU_PCROP_PROTECT_ENABLE */ +#if defined(TEST_ISOLATION) + {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_WRITE_FLASH}, /* WRP protection applies */ + {SE_CODE_REGION_ROM_END - SHIFT_FLASH_WRITE, "Isolated code end add", TEST_WRITE_FLASH},/* -7 : alignment for + 64bits writing test + WRP protection applies */ + {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_READ_FLASH}, + {SE_CODE_REGION_ROM_END, "Isolated code end add", TEST_READ_FLASH}, + {SE_STARTUP_REGION_ROM_START + 1U, "Isolated startup add", TEST_EXECUTE}, /* +1 : contains the SE startup code + that initializes all the variables in the binary. */ + {SE_CODE_REGION_ROM_START, "Isolated code start add", TEST_EXECUTE}, + {SE_CODE_REGION_ROM_END - 3U, "Isolated code end add", TEST_EXECUTE}, /* -3 : alignment for 32bits execute test */ + {SE_REGION_RAM_START, "Isolated Vdata add", TEST_WRITE_RAM}, + {SE_REGION_RAM_END - 3U, "Isolated Vdata add", TEST_WRITE_RAM}, /* -3 : alignment for 32bits writing test */ + {SE_REGION_RAM_START, "Isolated Vdata add", TEST_READ_RAM}, + {SE_REGION_RAM_END, "Isolated Vdata add", TEST_READ_RAM}, + {SE_REGION_RAM_START, "Isolated Vdata add", TEST_EXECUTE}, + {SE_REGION_RAM_END - 3U, "Isolated Vdata add", TEST_EXECUTE}, /* -3 : alignment for 32bits writing test */ + {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, + /* -8 : previous 64 bits for writing test */ + {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits + for reading test */ + {SLOT_ACTIVE_1_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits + for execute test */ + {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, + /* -8 : previous 64 bits for writing test */ + {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits + for reading test */ + {SLOT_ACTIVE_2_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits + for execute test */ + {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - (SHIFT_FLASH_WRITE + 1U), "Isolated NVdata add", TEST_WRITE_FLASH}, + /* -8 : previous 64 bits for writing test */ + {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - 1U, "Isolated NVdata add", TEST_READ_FLASH},/* -1 : previous 8bits + for reading test */ + {SLOT_ACTIVE_3_HEADER + SFU_IMG_IMAGE_OFFSET - 4U, "Isolated NVdata add", TEST_EXECUTE}, /* -4 : previous 32bits + for execute test */ +#endif /* TEST_ISOLATION */ +#ifdef SFU_MPU_PROTECT_ENABLE + /* Testing the MPU protection of the OBs */ + /* + * WL55JC + * 0x1FFF 7800 Reserved user option bytes & RDP (USER & RDP) + * 0x1FFF 7818 Reserved Write protection 1A + * 0x1FFF 7820 Reserved Write protection 1B + */ + {(uint32_t)0x1FFF7800, "OBs @ 0x1FFF7800", TEST_WRITE_FLASH}, + {(uint32_t)0x1FFF7818, "OBs @ 0x1FFF7818", TEST_WRITE_FLASH}, + {(uint32_t)0x1FFF7820, "OBs @ 0x1FFF7820", TEST_WRITE_FLASH}, +#endif /* SFU_MPU_PROTECT_ENABLE */ + {0xAAAAAAAA, "Execution successful", TEST_END}, +}; + + +/* Automatic test : list of operation */ +uint8_t aTestOperation[][20] = +{ + "write 8 bytes", + "read 1 byte", + "erase 512 bytes", + "write 4 bytes", + "read 1 byte", + "execute", + "end" +}; + +/* Private function prototypes -----------------------------------------------*/ +static void SFU_TEST_Protection(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Automatic test of PCROP/WRP/FWALL/MPU protections + * @param None. + * @retval None. + */ +static void SFU_TEST_Protection(void) +{ + uint32_t test_idx; + uint32_t flashErrCode = 0; + uint64_t pattern = 0U; + uint32_t page_error = 0U; + FLASH_EraseInitTypeDef p_erase_init; + TestStatus status = TEST_IN_PROGRESS; + __IO uint8_t tmp; + void (*func)(void); + + /* + * Now checking the security + * We will try to access protected @ and run protected code. + * Each time a a flash error will be raised or a reset will be generated by IP protection. + * At next boot we read the backup register to check the next @ until all addresses have been verified. + * WatchDog should be disabled : while(1) loop in case HardFault when trying to execute code @ address protected by + * FWALL/Code Isolation + */ + + do + { + /* slow down execution */ + HAL_Delay(100); + + /* Increment test number for next execution */ + test_idx = HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR1); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, (test_idx + 1)); + printf("\r\n= [TEST] %s @ %s %08x", aTestOperation[aProtectTests[test_idx].type], aProtectTests[test_idx].msg, + aProtectTests[test_idx].address); + + /* Remove test for slots not configured (taking into accounbt SFU_IMG_IMAGE_OFFSET) */ + if ((aProtectTests[test_idx].address != 0U) && (aProtectTests[test_idx].address < 0xFFFFFF00U) + && (aProtectTests[test_idx].address > 0x00000FFFU)) + { + switch (aProtectTests[test_idx].type) + { + /* Trying to write 64bits in FLASH : WRP flag is set for WRP or PCROP protected area + or reset generated if under FWALL or MPU protection */ + case TEST_WRITE_FLASH : + HAL_FLASH_Unlock(); + HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, aProtectTests[test_idx].address, pattern); + HAL_FLASH_Lock(); + flashErrCode = HAL_FLASH_GetError(); + printf("\r\nflash error code: %x", flashErrCode); + if ((flashErrCode & HAL_FLASH_ERROR_WRP) == 0U) + { + status = TEST_ERROR; + } + + /* + * OBs protection test: MPU generates a MEMORY FAULT and a RESET + * So the test is FAILED if we reach this line + */ + if (0 == strncmp("OBs @", (const char *)aProtectTests[test_idx].msg, 5)) + { + status = TEST_ERROR; + } + /* else not an OB protection test so probably not an error */ + break; + + /* Trying to read in FLASH : RDP set in case of PCROP protected area + or reset generated if under FWALL or MPU protection */ + case TEST_READ_FLASH : + tmp = *(uint8_t *)(aProtectTests[test_idx].address); + HAL_Delay(1); /* ensure Flag is set */ + /* + * When Isolation activated : RESET should be generated + * So the test is FAILED if we reach this line + */ + if (0 == strncmp("Isolated", (const char *)aProtectTests[test_idx].msg, 8)) + { + status = TEST_ERROR; + } + + break; + + /* Trying to erase 512 bytes in FLASH : WRP flag set for WRP or PCROP protected area + or reset generated if under FWALL or MPU protection */ + case TEST_ERASE_FLASH : + HAL_FLASH_Unlock(); + p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + p_erase_init.Page = SFU_LL_FLASH_GetPage(aProtectTests[test_idx].address); + p_erase_init.NbPages = 1; + HAL_FLASHEx_Erase(&p_erase_init, &page_error); + HAL_FLASH_Lock(); + if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) == 0U) + { + status = TEST_ERROR; + } + break; + + /* Trying to write in RAM : reset generated if under FWALL or MPU protection */ + case TEST_WRITE_RAM : + *(uint32_t *)aProtectTests[test_idx].address = 0x00000000; + status = TEST_ERROR; + break; + + /* Trying to read in RAM : reset generated if under FWALL or MPU protection */ + case TEST_READ_RAM : + tmp = *(uint8_t *)aProtectTests[test_idx].address; + printf(" value : %d ", tmp); + status = TEST_ERROR; + break; + + /* Tryning to execute code : reset generated if under FWALL or MPU protection */ + case TEST_EXECUTE : + func = (void(*)(void))(aProtectTests[test_idx].address); + func(); + status = TEST_ERROR; + break; + + /* End of execution */ + case TEST_END : + status = TEST_COMPLETED; + break; + + default : + break; + } + } + } while (status == TEST_IN_PROGRESS) ; + + if (status == TEST_ERROR) + { + SFU_TEST_Error(); + } + else if (status == TEST_COMPLETED) + { + /* reset for next run (need a RESET of the platform to restart a session) */ + printf("\b\b\b\b\b\b\b\b"); + printf("\r\nYou can RESET the platform to restart the tests.\r\n"); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_DONE); /* no more test in progress */ + } +} + +/** + * @brief Initialization of backup register and start test + * @param None. + * @retval None. + */ +void SFU_TEST_Init(void) +{ + /* Use register DR0 to know which if the test sequence is in progress or done */ + /* Use register DR1 to know which test to run after a reset */ + + if (MAGIC_TEST_DONE == HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0)) /* Test done */ + { + return; + } + else if (MAGIC_TEST_INIT != HAL_RTCEx_BKUPRead(&RtcHandle, + RTC_BKP_DR0)) /* Test not done nor in progress: Init magic (DR0) and + reset test index (DR1) */ + { + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_INIT); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, 0x0000); + } + + /* Start test */ + SFU_TEST_Protection(); +} + +/** + * @brief Reset backup register to be able to execute a new test sequence + * @param None. + * @retval None. + */ +void SFU_TEST_Reset(void) +{ + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_INIT); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR1, 0x0000); +} + +/** + * @brief Error detected during test sequence + * @param None. + * @retval None. + */ +void SFU_TEST_Error(void) +{ + printf(" ===> KO!!!!!"); + HAL_RTCEx_BKUPWrite(&RtcHandle, RTC_BKP_DR0, MAGIC_TEST_DONE); +} + +#endif /* SFU_TEST_PROTECTION */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_test.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_test.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/SBSFU/App/sfu_test.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_test.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_trace.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_trace.h new file mode 100644 index 00000000..cf6d3387 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/App/sfu_trace.h @@ -0,0 +1,80 @@ +/** + ****************************************************************************** + * @file sfu_trace.h + * @author MCD Application Team + * @brief This file contains definitions for SFU_TRACE functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_TRACE_H +#define SFU_TRACE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "app_sfu.h" +#if defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) +#include "sfu_com_trace.h" +#endif /* defined(SFU_DEBUG_MODE) || defined(SFU_TEST_PROTECTION) */ + +/* External variables --------------------------------------------------------*/ +/** + * This variable indicates if at boot-up the FW presence check has already been performed or not: + * \li It is reset when the FW status has already been checked once and no FW is present + * \li (see @ref SFU_BOOT_SM_CheckUserFwStatus) + * \li It is used to display some messages only once in the teraterm console + * \li It is used to determine if the user button must be pressed before waiting for a local download to start + * \li This is used at LocalDownload and CheckUserFwStatus stages. + */ +extern uint8_t initialDeviceStatusCheck; /* used also in sfu_fwimg_swap.c */ + +/* Exported macros -----------------------------------------------------------*/ +#ifdef SFU_DEBUG_MODE +#define TRACE_IRQ(pbuffer) (void) SFU_COM_Serial_PutString(pbuffer); /* Printf is not used inside interrupt to avoid + faults. printf is not rieentrant */ +#define TRACE (void) printf +#else +#define TRACE(...) +#define TRACE_IRQ(pbuffer) +#endif /* SFU_DEBUG_MODE */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_TRACE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level.c new file mode 100644 index 00000000..e637a536 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level.c @@ -0,0 +1,530 @@ +/** + ****************************************************************************** + * @file sfu_low_level.c + * @author MCD Application Team + * @brief SFU Low Level Interface module + * This file provides set of firmware functions to manage SFU low level + * interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SFU_LOW_LEVEL_C + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level.h" +#include "sfu_trace.h" + +#ifndef SFU_TAMPER_PROTECT_ENABLE +extern RTC_HandleTypeDef RtcHandle; +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + +/* Private variables ---------------------------------------------------------*/ +static UART_HandleTypeDef UartHandle; +static CRC_HandleTypeDef CrcHandle; + +/* Private function prototypes -----------------------------------------------*/ +static void SFU_LL_Error_Handler(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Initialize SFU Interface. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Initialize CRC */ + e_ret_status = SFU_LL_CRC_Init(); + + return e_ret_status; +} + +/** + * @brief DeInitialize SFU Interface. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_DeInit(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* ADD SRC CODE HERE + ... + */ + return e_ret_status; +} + +/** + * @brief SFU IF CRC Init. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_CRC_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Configure the peripheral clock */ + __HAL_RCC_CRC_CLK_ENABLE(); + + + /* Configure CRC with default polynomial - standard configuration */ + e_ret_status = SFU_LL_CRC_Config(SFU_CRC_CONFIG_DEFAULT); + + return e_ret_status; +} + +/** + * @brief SFU IF CRC Configuration. + * @param eCRCConfg: SFU_CRC_ConfigTypeDef. + * This parameter can be a value of @ref SFU_CRC_ConfigTypeDef. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_CRC_Config(SFU_CRC_ConfigTypeDef eCRCConfg) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + + /* Check the parameters */ + assert_param(IS_SFU_CRC_CONF(eCRCConfg)); + + /* Switch to the selected configuration */ + CrcHandle.Instance = CRC; + + /* The input data are not inverted */ + CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + + /* The output data are not inverted */ + CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + + switch (eCRCConfg) + { + case SFU_CRC_CONFIG_DEFAULT: + /* The Default polynomial is used */ + CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + /* The default init value is used */ + CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + /* The input data are 32-bit long words */ + CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS; + /* Valid parameter*/ + e_ret_status = SFU_SUCCESS; + break; + + case SFU_CRC_CONFIG_16BIT: + /* The CRC-16-CCIT polynomial is used */ + CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; + CrcHandle.Init.GeneratingPolynomial = 0x1021U; + CrcHandle.Init.CRCLength = CRC_POLYLENGTH_16B; + /* The zero init value is used */ + CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; + CrcHandle.Init.InitValue = 0U; + /* The input data are 8-bit long */ + CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + /* Valid parameter*/ + e_ret_status = SFU_SUCCESS; + break; + + default: + /* Invalid parameter */ + e_ret_status = SFU_ERROR; + break; + } + + /* Proceed to CRC Init (Correct Parameters) */ + if (e_ret_status == SFU_SUCCESS) + { + if (HAL_CRC_Init(&CrcHandle) != HAL_OK) + { + e_ret_status = SFU_ERROR; + } + } + + return e_ret_status; +} + + +/** + * @brief SFU IF CRC Calculate. + * @param pBuffer: pointer to data buffer. + * @param BufferLength: buffer length in bytes. + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +uint32_t SFU_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t BufferLength) +{ + return HAL_CRC_Calculate(&CrcHandle, pBuffer, BufferLength); +} + +/** + * @brief SFU UART Init. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_UART_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/ + /* USART configured as follow: + - BaudRate = 115200 baud + - Word Length = 8 Bits + - One Stop Bit + - No parity + - Hardware flow control disabled (RTS and CTS signals) + - Receive and transmit enabled + */ + UartHandle.Instance = SFU_UART; + UartHandle.Init.BaudRate = 115200U; + UartHandle.Init.WordLength = UART_WORDLENGTH_8B; + UartHandle.Init.StopBits = UART_STOPBITS_1; + UartHandle.Init.Parity = UART_PARITY_NONE; + UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle.Init.Mode = UART_MODE_RX | UART_MODE_TX; + UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; + UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; + if (HAL_UART_Init(&UartHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; + +} + +/** + * @brief SFU IF UART DeInit. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_UART_DeInit(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* + * ADD SRC CODE HERE + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; + +} + +/** + * @brief SFU IF Write data (send). + * @param pData: pointer to the 128bit data to write. + * @param DataLength: pointer to the 128bit data to write. + * @param pData: pointer to the 128bit data to write. + * @param Timeout: Timeout duration. + * @retval status of the write operation + * SFU_ERROR : if the write operation is not performed + * SFU_SUCCESS : if the write operation is successfully performed + */ +SFU_ErrorStatus SFU_LL_UART_Transmit(uint8_t *pData, uint16_t DataLength, uint32_t Timeout) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check the pointers allocation */ + if (pData == NULL) + { + return SFU_ERROR; + } + + if (HAL_UART_Transmit(&UartHandle, (uint8_t *)pData, DataLength, Timeout) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief SFU IF Read data (receive). + * @param pData: pointer to the 128bit data where to store the received data. + * @param DataLength: the length of the data to be read in bytes. + * @param Timeout: Timeout duration. + * @retval status of the read operation + * SFU_ERROR : if the read operation is not performed + * SFU_SUCCESS : if the read operation is successfully performed + */ +SFU_ErrorStatus SFU_LL_UART_Receive(uint8_t *pData, uint16_t DataLength, uint32_t Timeout) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check the pointers allocation */ + if (pData == NULL) + { + return SFU_ERROR; + } + + if (HAL_UART_Receive(&UartHandle, (uint8_t *)pData, DataLength, Timeout) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief SFU HAL IF Flush. + * @param None. + * @retval status of the operation. + */ +SFU_ErrorStatus SFU_LL_UART_Flush(void) +{ + /* Clean the input path */ + __HAL_UART_FLUSH_DRREGISTER(&UartHandle); + + return SFU_SUCCESS; +} + +#ifndef SFU_TAMPER_PROTECT_ENABLE +/** + * @brief SFU IF RTC Init. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_RTC_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Configure RTC prescaler and RTC data registers */ + /* RTC configured as follows: + - Hour Format = Format 24 + - Asynch Prediv = Value according to source clock + - Synch Prediv = Value according to source clock + - OutPut = Output Disable + - OutPutPolarity = High Polarity + - OutPutType = Open Drain */ + RtcHandle.Instance = RTC; + RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; + RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; + RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; + RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; + RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + + if (HAL_RTC_Init(&RtcHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief SFU IF RTC DeInit. + * @param None + * @retval status of the Init operation + * SFU_ERROR : if the Init operation failed. + * SFU_SUCCESS : if the Init operation is successfully performed. + */ +SFU_ErrorStatus SFU_LL_RTC_DeInit(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* + * ADD SRC CODE HERE + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; + +} + +#endif /*SFU_TAMPER_PROTECT_ENABLE*/ + +/** + * @brief SFU IF RTC MSP Initialization + * This function configures the hardware resources used in this example + * @param hrtc: RTC handle pointer. + * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select + * the RTC clock source; in this case the Backup domain will be reset in + * order to modify the RTC Clock source, as consequence RTC registers (including + * the backup registers) and RCC_BDCR register are set to their reset values. + * @retval None + */ +void SFU_LL_RTC_MspInit(RTC_HandleTypeDef *hrtc) +{ + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + UNUSED(hrtc); + /*-1- Enables access to the backup domain */ + /* To enable access on RTC registers */ + + HAL_PWR_EnableBkUpAccess(); + + /*-2- Configure LSE/LSI as RTC clock source */ +#ifdef RTC_CLOCK_SOURCE_LSE + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_OFF; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } +#elif defined (RTC_CLOCK_SOURCE_LSI) + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.LSIDiv = LL_RCC_LSI_PREDIV_1; + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + SFU_LL_Error_Handler(); + } +#else +#error Please select the RTC Clock source inside the main.h file +#endif /*RTC_CLOCK_SOURCE_LSE*/ + + /*-3- Enable RTC peripheral Clocks */ + /* Enable RTC Clock */ + __HAL_RCC_RTC_ENABLE(); + + /* Enable RTC APB clock */ + __HAL_RCC_RTCAPB_CLK_ENABLE(); +#ifdef SFU_TAMPER_PROTECT_ENABLE + /*-4- Configure the NVIC for RTC Tamper */ + HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, 0x0FU, 0U); + HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); +#endif /* SFU_TAMPER_PROTECT_ENABLE */ +} + +/** + * @brief RTC MSP De-Initialization + * This function frees the hardware resources used in in SFU application: + * - Disable the Peripheral's clock + * @param hrtc: RTC handle pointer + * @retval None + */ +void SFU_LL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc) +{ + UNUSED(hrtc); + + __HAL_RCC_RTC_DISABLE(); + + /* Disable RTC APB clock */ + __HAL_RCC_RTCAPB_CLK_DISABLE(); +} + +/** + * @brief UART MSP Initialization + * This function configures the hardware resources used in SFU application. + * @param huart: UART handle pointer + * @retval None + */ +void SFU_LL_UART_MspInit(UART_HandleTypeDef *huart) +{ + + GPIO_InitTypeDef GPIO_InitStruct; + if (huart->Instance == SFU_UART) + { + /* Peripheral Clock Enable */ + SFU_UART_CLK_ENABLE(); + + /* GPIO Ports Clock Enable */ + SFU_UART_TX_GPIO_CLK_ENABLE(); + SFU_UART_RX_GPIO_CLK_ENABLE(); + + /*Configure GPIO pins : SFU_UART_TX_Pin */ + GPIO_InitStruct.Pin = SFU_UART_TX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = SFU_UART_TX_AF; + HAL_GPIO_Init(SFU_UART_TX_GPIO_PORT, &GPIO_InitStruct); + + /*Configure GPIO pins : SFU_UART_RX_Pin */ + GPIO_InitStruct.Pin = SFU_UART_RX_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = SFU_UART_RX_AF; + HAL_GPIO_Init(SFU_UART_RX_GPIO_PORT, &GPIO_InitStruct); + + } + +} + +/** + * @brief UART MSP De-Initialization + * This function frees the hardware resources used in SFU application: + * - Disable the Peripheral's clock + * @param huart: UART handle pointer + * @retval None + */ +void SFU_LL_UART_MspDeInit(UART_HandleTypeDef *huart) +{ + + if (huart->Instance == SFU_UART) + { + /* Peripheral clock disable */ + SFU_UART_CLK_DISABLE(); + + /* GPIO DeInit*/ + HAL_GPIO_DeInit(SFU_UART_TX_GPIO_PORT, SFU_UART_TX_PIN); + HAL_GPIO_DeInit(SFU_UART_RX_GPIO_PORT, SFU_UART_RX_PIN); + + } + + +} + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +static void SFU_LL_Error_Handler(void) +{ + /* + * ADD SRC CODE HERE + */ + + while (1 == 1) + { + NVIC_SystemReset(); + } +} + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level.h new file mode 100644 index 00000000..3532844d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * @file sfu_low_level.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update low level + * interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_H +#define SFU_LOW_LEVEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief SFU CRC Configuration definition + */ +typedef enum +{ + SFU_CRC_CONFIG_NONE = 0U, /*!< None */ + SFU_CRC_CONFIG_DEFAULT, /*!< Default configuration */ + SFU_CRC_CONFIG_16BIT /*!< 16 bit configuration */ +} SFU_CRC_ConfigTypeDef; + +/* Exported constants --------------------------------------------------------*/ +#define SFU_UART USART2 +#define SFU_UART_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() +#define SFU_UART_CLK_DISABLE() __HAL_RCC_USART2_CLK_DISABLE() + +#define SFU_UART_TX_AF GPIO_AF7_USART2 +#define SFU_UART_TX_GPIO_PORT GPIOA +#define SFU_UART_TX_PIN GPIO_PIN_2 +#define SFU_UART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_UART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() + +#define SFU_UART_RX_AF GPIO_AF7_USART2 +#define SFU_UART_RX_GPIO_PORT GPIOA +#define SFU_UART_RX_PIN GPIO_PIN_3 +#define SFU_UART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_UART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() + +/* Uncomment to enable the adequate Clock Source */ +#define RTC_CLOCK_SOURCE_LSI +/*#define RTC_CLOCK_SOURCE_LSE*/ + +#ifdef RTC_CLOCK_SOURCE_LSI +#define RTC_ASYNCH_PREDIV 0x1FU +#define RTC_SYNCH_PREDIV 0x3FF +#endif /* RTC_CLOCK_SOURCE_LSI */ + +#ifdef RTC_CLOCK_SOURCE_LSE +#define RTC_ASYNCH_PREDIV 0x7FU +#define RTC_SYNCH_PREDIV 0x00FFU +#endif /* RTC_CLOCK_SOURCE_LSE */ + +/* External variables --------------------------------------------------------*/ +extern __IO uint32_t DummyMemAccess; +#if defined(SFU_LOW_LEVEL_C) +#if defined(IT_MANAGEMENT) + +/* Dummy memory access : avoid compilation issue with STM32_Secure_Engine middleware + but not meaningful for this product */ +__IO uint32_t DummyMemAccess; +#endif /* defined(IT_MANAGEMENT) */ +#endif /* defined(SFU_LOW_LEVEL_C) */ + + +/* Exported macros -----------------------------------------------------------*/ +#define IS_SFU_CRC_CONF(CONF) (((CONF) == SFU_CRC_CONFIG_NONE) || \ + ((CONF) == SFU_CRC_CONFIG_DEFAULT) || \ + ((CONF) == SFU_CRC_CONFIG_16BIT)) + +/* Dummy memory access : avoid compilation issue with STM32_Secure_Engine middleware + but not meaningful for this product */ +#define SFU_LL_DummyAccess() \ + do{ \ + }while(0) + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_Init(void); +SFU_ErrorStatus SFU_LL_DeInit(void); + +SFU_ErrorStatus SFU_LL_CRC_Init(void); +SFU_ErrorStatus SFU_LL_CRC_Config(SFU_CRC_ConfigTypeDef eCRCConfg); +uint32_t SFU_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t BufferLength); + +SFU_ErrorStatus SFU_LL_UART_Init(void); +SFU_ErrorStatus SFU_LL_UART_DeInit(void); +SFU_ErrorStatus SFU_LL_UART_Transmit(uint8_t *pData, uint16_t DataLength, uint32_t Timeout); +SFU_ErrorStatus SFU_LL_UART_Receive(uint8_t *pData, uint16_t DataLength, uint32_t Timeout); +SFU_ErrorStatus SFU_LL_UART_Flush(void); + +#ifndef SFU_TAMPER_PROTECT_ENABLE +SFU_ErrorStatus SFU_LL_RTC_Init(void); +SFU_ErrorStatus SFU_LL_RTC_DeInit(void); +#endif /*SFU_TAMPER_PROTECT_ENABLE*/ + +void SFU_LL_RTC_MspInit(RTC_HandleTypeDef *hrtc); +void SFU_LL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc); +void SFU_LL_UART_MspInit(UART_HandleTypeDef *huart); +void SFU_LL_UART_MspDeInit(UART_HandleTypeDef *huart); + + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash.c new file mode 100644 index 00000000..4cea3348 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash.c @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash.c + * @author MCD Application Team + * @brief SFU Flash Low Level Interface module + * This file provides set of firmware functions to manage SFU flash + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_flash_ext.h" +#include "sfu_fwimg_regions.h" + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Initialize internal and external flash interface (OSPI/QSPI) + * @param none + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Init(void) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + + e_ret_status = SFU_LL_FLASH_INT_Init(); + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_FLASH_EXT_Init(); + } + return e_ret_status; +} + +/** + * @brief Depending on start address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pFlashStatus: SFU_FLASH Status pointer + * @param pStart: flash address to be erased + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) +{ + + /* Check Flash start address */ + if ((uint32_t) pStart < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Erase_Size(pFlashStatus, pStart, Length); + } + else + { + return SFU_LL_FLASH_EXT_Erase_Size(pFlashStatus, pStart, Length); + } +} + +/** + * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pFlashStatus: FLASH_StatusTypeDef + * @param pDestination: flash address to write + * @param pSource: pointer on buffer with data to write + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length) +{ + /* Check Flash destination address */ + if ((uint32_t) pDestination < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Write(pFlashStatus, pDestination, pSource, Length); + } + else + { + return SFU_LL_FLASH_EXT_Write(pFlashStatus, pDestination, pSource, Length); + } +} + +/** + * @brief Depending on source address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pDestination: pointer on buffer to store data + * @param pSource: flash address to read + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + /* Check Flash source address */ + if ((uint32_t) pSource < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Read(pDestination, pSource, Length); + } + else + { + return SFU_LL_FLASH_EXT_Read(pDestination, pSource, Length); + } +} + +/** + * @brief This function compare a buffer with a flash area + * @note The flash area should not be located inside the secure area + * @param pFlash: address of the flash area + * @param Pattern1: first 32 bits pattern to be compared + * @param Pattern2: second 32 bits pattern to be compared + * @param Length: number of bytes to be compared + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length) +{ + /* Check Flash source address */ + if ((uint32_t) pFlash < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_Compare(pFlash, Pattern1, Pattern2, Length); + } + else + { + return SFU_LL_FLASH_EXT_Compare(pFlash, Pattern1, Pattern2, Length); + } +} + +/** + * @brief This function configure the flash to be able to execute code + * @param Addr: flash address + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_Config_Exe(uint32_t SlotNumber) +{ + /* + * Internal flash : nothing to do + * External flash : configure memory mapped mode + */ + + /* Check Flash address */ + if (SlotStartAdd[SlotNumber] < EXTERNAL_FLASH_ADDRESS) + { + return SFU_SUCCESS; + } + else + { + return SFU_LL_FLASH_EXT_Config_Exe(SlotNumber); + } +} + +/** + * @brief Gets the page of a given address + * @param Addr: flash address + * @retval The page of a given address + */ +uint32_t SFU_LL_FLASH_GetPage(uint32_t Addr) +{ + /* Check Flash address */ + if (Addr < EXTERNAL_FLASH_ADDRESS) + { + return SFU_LL_FLASH_INT_GetPage(Addr); + } + else + { + return INVALID_PAGE; /* Page number is not used in SBSFU application for external flash */ + } +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash.h new file mode 100644 index 00000000..726365d6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update flash + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_FLASH_H +#define SFU_LOW_LEVEL_FLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + SFU_FLASH_ERROR = 0U, /*!< Error Flash generic*/ + SFU_FLASH_ERR_HAL, /*!< Error Flash HAL init */ + SFU_FLASH_ERR_ERASE, /*!< Error Flash erase */ + SFU_FLASH_ERR_WRITING, /*!< Error writing data in Flash */ + SFU_FLASH_ERR_WRITINGCTRL, /*!< Error checking data written in Flash */ + SFU_FLASH_SUCCESS /*!< Flash Success */ +} SFU_FLASH_StatusTypeDef; + +/* Exported constants --------------------------------------------------------*/ +#define INVALID_SECTOR 0xFFFFFFFFU +#define INVALID_PAGE 0xFFFFFFFFU +#define INVALID_BANK 0xFFFFFFFFU + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_FLASH_Init(void); +SFU_ErrorStatus SFU_LL_FLASH_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_Config_Exe(uint32_t SlotNumber); + +uint32_t SFU_LL_FLASH_GetPage(uint32_t Addr); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_FLASH_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c new file mode 100644 index 00000000..7b10b14d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c @@ -0,0 +1,80 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_ext.c + * @author MCD Application Team + * @brief SFU Flash Low Level Interface module + * This file provides set of firmware functions to manage SFU external + * flash low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level_flash_ext.h" +#include "sfu_low_level_security.h" + +/* Private defines -----------------------------------------------------------*/ + +/* Functions Definition ------------------------------------------------------*/ + +/* No external flash available on this product + ==> return SFU_ERROR except for SFU_LL_FLASH_EXT_Init and SFU_LL_FLASH_EXT_Config_Exe which are called + systematically during startup phase */ + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Init(void) +{ + return SFU_SUCCESS; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) +{ + UNUSED(pFlashStatus); + UNUSED(pStart); + UNUSED(Length); + return SFU_ERROR; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length) +{ + UNUSED(pFlashStatus); + UNUSED(pDestination); + UNUSED(pSource); + UNUSED(Length); + return SFU_ERROR; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + UNUSED(pDestination); + UNUSED(pSource); + UNUSED(Length); + return SFU_ERROR; +} + +SFU_ErrorStatus SFU_LL_FLASH_EXT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length) +{ + UNUSED(pFlash); + UNUSED(Pattern1); + UNUSED(Pattern2); + UNUSED(Length); + return SFU_ERROR; +} +SFU_ErrorStatus SFU_LL_FLASH_EXT_Config_Exe(uint32_t SlotNumber) +{ + UNUSED(SlotNumber); + return SFU_SUCCESS; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h new file mode 100644 index 00000000..08566d80 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_ext.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update low level + * interface for external flash. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_FLASH_EXT_H +#define SFU_LOW_LEVEL_FLASH_EXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_low_level_flash.h" +#include "main.h" +#include "sfu_def.h" + +/* Exported constants --------------------------------------------------------*/ +#define EXTERNAL_FLASH_ADDRESS 0x90000000U + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_FLASH_EXT_Init(void); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_EXT_Config_Exe(uint32_t SlotNumber); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_FLASH_EXT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c new file mode 100644 index 00000000..1e8db303 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c @@ -0,0 +1,474 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_int.c + * @author MCD Application Team + * @brief SFU Flash Low Level Interface module + * This file provides set of firmware functions to manage SFU internal + * flash low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level_security.h" +#include "se_interface_bootloader.h" +#include "string.h" +#include "sfu_fsm_states.h" +#include "sfu_error.h" + +/* Private defines -----------------------------------------------------------*/ +#define NB_PAGE_SECTOR_PER_ERASE 2U /*!< Nb page erased per erase */ + +/* Private variables ---------------------------------------------------------*/ +static __IO uint32_t DoubleECC_Error_Counter = 0U; + + +static SFU_ErrorStatus SFU_LL_FLASH_INT_Clear_Error(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief This function initialize the internal flash interface if required + * @param none + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Init(void) +{ + return SFU_SUCCESS; +} + +/** + * @brief This function does an erase of n (depends on Length) pages in user flash area + * @param pFlashStatus: SFU_FLASH Status pointer + * @param pStart: flash address to be erased + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Erase_Size(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pStart, uint32_t Length) +{ + uint32_t page_error = 0U; + uint32_t start = (uint32_t)pStart; + FLASH_EraseInitTypeDef p_erase_init; + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t first_page; + uint32_t nb_pages; + uint32_t chunk_nb_pages; + uint32_t length = Length; + + /* Check the pointers allocation */ + if (pFlashStatus == NULL) + { + return SFU_ERROR; + } + + *pFlashStatus = SFU_FLASH_SUCCESS; + + /* Clear error flags raised during previous operation */ + e_ret_status = SFU_LL_FLASH_INT_Clear_Error(); + + if (e_ret_status == SFU_SUCCESS) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + first_page = SFU_LL_FLASH_INT_GetPage(start); + /* Get the number of pages to erase from 1st page */ + nb_pages = SFU_LL_FLASH_INT_GetPage(start + length - 1U) - first_page + 1U; + p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + /* Erase flash per NB_PAGE_SECTOR_PER_ERASE to avoid watch-dog */ + do + { + chunk_nb_pages = (nb_pages >= NB_PAGE_SECTOR_PER_ERASE) ? NB_PAGE_SECTOR_PER_ERASE : nb_pages; + p_erase_init.Page = first_page; + p_erase_init.NbPages = chunk_nb_pages; + first_page += chunk_nb_pages; + nb_pages -= chunk_nb_pages; + if (HAL_FLASHEx_Erase(&p_erase_init, &page_error) != HAL_OK) + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERR_ERASE; + } + SFU_LL_SECU_IWDG_Refresh(); /* calling this function which checks the compiler switch */ + } while (nb_pages > 0U); + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + if (HAL_FLASH_Lock() != HAL_OK) + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERR_HAL; + } + } + else + { + *pFlashStatus = SFU_FLASH_ERR_HAL; + } + } + + return e_ret_status; +} + +/** + * @brief This function writes a data buffer in flash (data are 32-bit aligned). + * @note After writing data buffer, the flash content is checked. + * @param pFlashStatus: FLASH_StatusTypeDef + * @param pDestination: Start address for target location. It has to be 8 bytes aligned. + * @param pSource: pointer on buffer with data to write + * @param Length: Length of data buffer in bytes. It has to be 8 bytes aligned. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Write(SFU_FLASH_StatusTypeDef *pFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint32_t i; + uint32_t inside_header = 0U; + uint32_t destination = (uint32_t)pDestination; + uint32_t source = (uint32_t)pSource; + + /* Check the pointers allocation */ + if ((pFlashStatus == NULL) || (pSource == NULL)) + { + return SFU_ERROR; + } + + /* Is destination area inside 1 of the firmware image headers ? */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((destination >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((destination + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + inside_header = 1U; + } + } + + /* Destination area part of 1 of the firmware image headers : + writing operation should be executed inside secure environment */ + if ((inside_header == 1U) && (Length != 0U)) + { + /* SE Access */ + SE_StatusTypeDef se_status; + SE_ErrorStatus se_ret_status = SE_SFU_IMG_Write(&se_status, (uint8_t *)destination, pSource, Length); + if (se_ret_status == SE_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + *pFlashStatus = SFU_FLASH_SUCCESS; + } + else + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERROR; + } + } + /* Writing operation executed by SBSFU */ + else + { + *pFlashStatus = SFU_FLASH_ERROR; + + /* Clear error flags raised during previous operation */ + e_ret_status = SFU_LL_FLASH_INT_Clear_Error(); + + if (e_ret_status == SFU_SUCCESS) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() != HAL_OK) + { + *pFlashStatus = SFU_FLASH_ERR_HAL; + + } + else + { + /* DataLength must be a multiple of 64 bit */ + for (i = 0U; (i < Length) && (e_ret_status == SFU_SUCCESS); i += sizeof(SFU_LL_FLASH_write_t)) + { + *pFlashStatus = SFU_FLASH_ERROR; + + /* Device voltage range supposed to be [2.7V to 3.6V], the operation will + be done by word */ + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, destination, *((uint64_t *)(source + i))) + == HAL_OK) + { + /* Check the written value */ + if (*(uint64_t *)destination != *(uint64_t *)(source + i)) + { + /* Flash content doesn't match SRAM content */ + *pFlashStatus = SFU_FLASH_ERR_WRITINGCTRL; + e_ret_status = SFU_ERROR; + } + else + { + /* Increment FLASH Destination address */ + destination = destination + sizeof(SFU_LL_FLASH_write_t); + e_ret_status = SFU_SUCCESS; + *pFlashStatus = SFU_FLASH_SUCCESS; + } + } + else + { + /* Error occurred while writing data in Flash memory */ + *pFlashStatus = SFU_FLASH_ERR_WRITING; + e_ret_status = SFU_ERROR; + } + } + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) */ + if (HAL_FLASH_Lock() != HAL_OK) + { + e_ret_status = SFU_ERROR; + *pFlashStatus = SFU_FLASH_ERR_HAL; + } + } + } + } + return e_ret_status; +} + +/** + * @brief This function reads flash + * @param pDestination: Start address for target location + * @param pSource: flash address to read + * @param Length: number of bytes + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + SE_ErrorStatus se_ret_status; + SE_StatusTypeDef se_status; + uint32_t i; + uint32_t inside_header = 0U; + uint32_t source = (uint32_t)pSource; + + /* Is destination area inside 1 of the firmware image headers ? */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((source >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((source + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + inside_header = 1U; + } + } + + /* Destination area part of 1 of the firmware image headers : + reading operation should be executed inside secure environment */ + if (inside_header == 1U) + { + /* SE Access */ + DoubleECC_Error_Counter = 0U; + se_ret_status = SE_SFU_IMG_Read(&se_status, pDestination, (uint8_t *)source, Length); + if ((se_ret_status == SE_SUCCESS) && (DoubleECC_Error_Counter == 0U)) + { + e_ret_status = SFU_SUCCESS; + } + DoubleECC_Error_Counter = 0U; + } + /* Reading operation executed by SBSFU */ + else + { + DoubleECC_Error_Counter = 0U; + /* Do not use memcpy from lib : ECC error should be checked at each loop */ + for (i = 0; (i < Length) && (DoubleECC_Error_Counter == 0U); i++, pDestination++, pSource++) + { + *pDestination = *pSource; + } + if (DoubleECC_Error_Counter == 0U) + { + e_ret_status = SFU_SUCCESS; + } + DoubleECC_Error_Counter = 0U; + } + return e_ret_status; +} + +/** + * @brief This function compare a buffer with a flash area + * @note The flash area should not be located inside the secure area + * @param pFlash: address of the flash area + * @param Pattern1: first 32 bits pattern to be compared + * @param Pattern2: second 32 bits pattern to be compared + * @param Length: number of bytes to be compared + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length) +{ + uint32_t flash = (uint32_t) pFlash; + uint32_t i; + + /* Comparison executed by SBSFU ==> flash area could not be located inside secured environment */ + for ( i = 0U; i < Length; i += 4U) + { + if ((*(uint32_t *)(flash + i) != Pattern1) && (*(uint32_t *)(flash + i) != Pattern2)) + { + return SFU_ERROR; + } + } + return SFU_SUCCESS; +} + +/** + * @brief Gets the page of a given address + * @param Addr: flash address + * @retval The page of a given address + */ +uint32_t SFU_LL_FLASH_INT_GetPage(uint32_t Addr) +{ + uint32_t page; + + page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE; + + return page; +} + + + + +/** + * @brief Clear error flags raised during previous operation + * @param None. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus SFU_LL_FLASH_INT_Clear_Error(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Unlock the Program memory */ + if (HAL_FLASH_Unlock() == HAL_OK) + { + + /* Clear all FLASH flags */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); + + /* Unlock the Program memory */ + if (HAL_FLASH_Lock() == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } + } + + return e_ret_status; + +} + + +/** + * @brief Get Link Register value (LR) + * @param None. + * @retval LR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_LR(void) +{ + register uint32_t result; + +#if defined ( __ICCARM__ ) || ( __GNUC__ ) + __ASM volatile("MOV %0, LR" : "=r"(result)); +#elif defined ( __CC_ARM ) + __ASM volatile("MOV result, __return_address()"); +#endif /* ( __ICCARM__ ) || ( __GNUC__ ) */ + + return result; +} + +/* + As this handler code relies on stack pointer position to manipulate the PC return value, it is important + not to use extra registers (on top of scratch registers), because it would change the stack pointer + position. Then compiler optimizations are customized to ensure that. +*/ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O1"))) +#endif /* __ICCARM__ */ +/** + * @brief NMI Handler present for handling Double ECC NMI interrupt + * @param None. + * @retvat void + */ +void NMI_Handler(void) +{ + uint32_t *p_sp; + uint32_t lr; + uint16_t opcode_msb; + + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)) + { + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); + + /* Memorize error to ignore the read value */ + DoubleECC_Error_Counter++; + + lr = __get_LR(); + + /* Check EXC_RETURN value in LR to know which SP was used prior entering exception */ + if (((lr) & (0xFU)) == 0xDU) + { + /* interrupted code was using Process Stack Pointer */ + p_sp = (uint32_t *)__get_PSP(); + } + else + { + /* interrupted code was using Main Stack Pointer */ + p_sp = (uint32_t *)__get_MSP(); + } + + /* Test caller mode T bit from CPSR in stack */ + if ((*(p_sp + 7U) & (1U << xPSR_T_Pos)) != 0U) + { + /* Thumb mode. + Test PC in stack. + If bits [15:11] of the halfword being decoded take any of the following values, + the halfword is the first halfword of a 32-bit instruction: 0b11101, 0b11110, 0b11111. + Otherwise, the halfword is a 16-bit instruction. + */ + opcode_msb = (*(uint16_t *)(*(p_sp + 6) & 0xFFFFFFFEU) & 0xF800U); + if ((opcode_msb == 0xE800U) || (opcode_msb == 0xF000U) || (opcode_msb == 0xF800U)) + { + /* execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + else + { + /* execute next instruction PC +2 */ + *(p_sp + 6U) += 2U; + } + } + else + { + /* ARM mode execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + } + else + { + while (1 == 1) + { + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_UNKNOWN); + } + } +} + + +/** + * @brief HardFault Handler + * @param None. + * @retval None. + */ +void HardFault_Handler(void) +{ + SFU_EXCPT_IrqExceptionHandler(SFU_EXCPT_HARD_FAULT); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h new file mode 100644 index 00000000..5ef51fc6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file sfu_low_level_flash_int.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update low level + * interface for internal flash. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_FLASH_INT_H +#define SFU_LOW_LEVEL_FLASH_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_low_level_flash.h" +#include "main.h" +#include "sfu_def.h" + +/* Exported types ------------------------------------------------------------*/ +/** + * @brief Flash Write Access Constraints (size and alignment) + * + * For instance, on L4, it is only possible to program double word (2 x 32-bit data). + * See http://www.st.com/content/ccc/resource/technical/document/reference_manual/02/35/09/0c/4f/f7/40/03/DM00083560.pdf/files/DM00083560.pdf/jcr:content/translations/en.DM00083560.pdf + * + * @note This type is very important for the FWIMG module (see @ref SFU_IMG). + * \li This is the type to be used for an atomic write in FLASH: see @ref AtomicWrite. + * \li The size of this type changes the size of the TRAILER area at the end of dwl slot, + * as it is used to tag if a Firmware Image chunk has been swapped or not (see @ref SFU_IMG_FirmwareToResume). + */ + +/* double-word is the default setting for most platforms */ +typedef uint64_t SFU_LL_FLASH_write_t; + +/* Exported constants --------------------------------------------------------*/ +/** + * Length of a MAGIC tag (32 bytes). + * This must be a multiple of @ref SFU_LL_FLASH_write_t with a minimum value of 32. + */ +#define MAGIC_LENGTH ((uint32_t)32U) + +/* External variables --------------------------------------------------------*/ +#define IS_ALIGNED(address) (0U == ((address) % FLASH_PAGE_SIZE)) + +/* Exported functions ------------------------------------------------------- */ +SFU_ErrorStatus SFU_LL_FLASH_INT_Init(void); +SFU_ErrorStatus SFU_LL_FLASH_INT_Erase_Size(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pStart, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_INT_Write(SFU_FLASH_StatusTypeDef *pxFlashStatus, uint8_t *pDestination, + const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_INT_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SFU_ErrorStatus SFU_LL_FLASH_INT_Compare(const uint8_t *pFlash, const uint32_t Pattern1, const uint32_t Pattern2, uint32_t Length); +uint32_t SFU_LL_FLASH_INT_GetPage(uint32_t Addr); +void NMI_Handler(void); +void HardFault_Handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SFU_LOW_LEVEL_FLASH_INT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_security.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_security.c new file mode 100644 index 00000000..f6411633 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_security.c @@ -0,0 +1,1102 @@ +/** + ****************************************************************************** + * @file sfu_low_level_security.c + * @author MCD Application Team + * @brief SFU Security Low Level Interface module + * This file provides set of firmware functions to manage SFU security + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level_security.h" +#include "sfu_low_level_flash_int.h" +#include "sfu_low_level.h" +#include "sfu_trace.h" +#include "sfu_boot.h" +#include "sfu_fsm_states.h" /* needed for sfu_error.h */ +#include "sfu_error.h" +#include "stm32wlxx_it.h" + +#ifndef SFU_WRP_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_WRP_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_WRP_PROTECT_ENABLE */ + +#ifndef SFU_RDP_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_RDP_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_RDP_PROTECT_ENABLE */ + + +#ifndef SFU_MPU_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_MPU_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_MPU_PROTECT_ENABLE */ + + + +#ifndef SFU_TAMPER_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_TAMPER_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + +#ifndef SFU_DAP_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_DAP_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_DAP_PROTECT_ENABLE */ + +#ifndef SFU_DMA_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_DMA_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_DMA_PROTECT_ENABLE */ + +#ifndef SFU_IWDG_PROTECT_ENABLE +#if !defined(SECBOOT_DISABLE_SECURITY_IPS) +#warning "SFU_IWDG_PROTECT_DISABLED" +#endif /* !SECBOOT_DISABLE_SECURITY_IPS */ +#endif /* SFU_IWDG_PROTECT_ENABLE */ + + +/* Private typedef -----------------------------------------------------------*/ +typedef enum +{ + SFU_FALSE = 0U, + SFU_TRUE = !SFU_FALSE +} SFU_BoolTypeDef; + +typedef struct +{ + uint8_t Number; /*!< Specifies the number of the region to protect. This parameter can be a + value of CORTEX_MPU_Region_Number */ + uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */ + uint8_t Size; /*!< Specifies the size of the region to protect. */ + uint8_t AccessPermission; /*!< Specifies the region access permission type. This parameter can be a + value of CORTEX_MPU_Region_Permission_Attributes */ + uint8_t DisableExec; /*!< Specifies the instruction access status. This parameter can be a value + of CORTEX_MPU_Instruction_Access */ + uint8_t SubRegionDisable; /*!< Specifies the sub region field (region is divided in 8 slices) when bit + is 1 region sub region is disabled */ +} SFU_MPU_InitTypeDef; + +typedef uint32_t SFU_ProtectionTypeDef; /*!< SFU HAL IF Protection Type Def*/ + +/* Private variables ---------------------------------------------------------*/ +#ifdef SFU_IWDG_PROTECT_ENABLE +static IWDG_HandleTypeDef IwdgHandle; + +#endif /* SFU_IWDG_PROTECT_ENABLE */ +#ifdef SFU_MPU_PROTECT_ENABLE +static SFU_MPU_InitTypeDef MpuAreas[] = + + { + { + MPU_REGION_NUMBER0, SFU_PROTECT_MPU_AREA_USER_START, SFU_PROTECT_MPU_AREA_USER_SIZE, + SFU_PROTECT_MPU_AREA_USER_PERM, SFU_PROTECT_MPU_AREA_USER_EXEC, SFU_PROTECT_MPU_AREA_USER_SREG + }, +{ + MPU_REGION_NUMBER1, SFU_PROTECT_MPU_AREA_SFUEN_START_0, SFU_PROTECT_MPU_AREA_SFUEN_SIZE_0, + SFU_PROTECT_MPU_AREA_SFUEN_PERM, SFU_PROTECT_MPU_AREA_SFUEN_EXEC, SFU_PROTECT_MPU_AREA_SFUEN_SREG_0 +}, +{ + MPU_REGION_NUMBER2, SFU_PROTECT_MPU_AREA_SFUEN_START_1, SFU_PROTECT_MPU_AREA_SFUEN_SIZE_1, + SFU_PROTECT_MPU_AREA_SFUEN_PERM, SFU_PROTECT_MPU_AREA_SFUEN_EXEC, SFU_PROTECT_MPU_AREA_SFUEN_SREG_1 +}, +{ + MPU_REGION_NUMBER3, SFU_PROTECT_MPU_AREA_VECT_START, SFU_PROTECT_MPU_AREA_VECT_SIZE, + SFU_PROTECT_MPU_AREA_VECT_PERM, SFU_PROTECT_MPU_AREA_VECT_EXEC, SFU_PROTECT_MPU_AREA_VECT_SREG +}, +{ + MPU_REGION_NUMBER4, SFU_PROTECT_MPU_AREA_OB_BANK1_START, SFU_PROTECT_MPU_AREA_OB_BANK1_SIZE, + SFU_PROTECT_MPU_AREA_OB_BANK1_PERM, SFU_PROTECT_MPU_AREA_OB_BANK1_EXEC, SFU_PROTECT_MPU_AREA_OB_BANK1_SREG +}, +{ + MPU_REGION_NUMBER5, SFU_PROTECT_MPU_AREA_PERIPH_START, SFU_PROTECT_MPU_AREA_PERIPH_SIZE, + SFU_PROTECT_MPU_AREA_PERIPH_PERM, SFU_PROTECT_MPU_AREA_PERIPH_EXEC, SFU_PROTECT_MPU_AREA_PERIPH_SREG +}, + }; +#endif /* SFU_MPU_PROTECT_ENABLE */ + +/* Private function prototypes -----------------------------------------------*/ +static SFU_ErrorStatus SFU_LL_SECU_CheckFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes); +static SFU_ErrorStatus SFU_LL_SECU_SetFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied); + +#ifdef SFU_RDP_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionRDP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied); +#endif /*SFU_RDP_PROTECT_ENABLE*/ + +#ifdef SFU_WRP_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_CheckProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes); +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied); +#endif /*SFU_WRP_PROTECT_ENABLE*/ + + + + +#ifdef SFU_IWDG_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionIWDG(void); +#endif /*SFU_IWDG_PROTECT_ENABLE*/ + +#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionCLOCK_MONITOR(void); +#endif /*SFU_CLCK_MNTR_PROTECT_ENABLE*/ + +#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE +static SFU_ErrorStatus SFU_LL_SECU_SetProtectionTEMP_MONITOR(void); +#endif /*SFU_TEMP_MNTR_PROTECT_ENABLE*/ + + + +/* Functions Definition : helper ---------------------------------------------*/ +#ifdef SFU_MPU_PROTECT_ENABLE +/** + * @brief Check MPU configuration + * @param MPU_InitStruct Configuration to be checked + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +static SFU_ErrorStatus MPU_CheckConfig(MPU_Region_InitTypeDef *pMPUInitStruct) +{ + uint32_t mpu_rasr = 0UL; + + /* Set the Region number */ + MPU->RNR = pMPUInitStruct->Number; + + mpu_rasr |= (((uint32_t)pMPUInitStruct->DisableExec << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->AccessPermission << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->TypeExtField << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->IsShareable << MPU_RASR_S_Pos) & MPU_RASR_S_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->IsCacheable << MPU_RASR_C_Pos) & MPU_RASR_C_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->IsBufferable << MPU_RASR_B_Pos) & MPU_RASR_B_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->SubRegionDisable << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->Size << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk); + mpu_rasr |= (((uint32_t)pMPUInitStruct->Enable << MPU_RASR_ENABLE_Pos) & MPU_RASR_ENABLE_Msk); + + if (((MPU->RBAR & MPU_RBAR_ADDR_Msk) == pMPUInitStruct->BaseAddress) && (MPU->RASR == mpu_rasr)) + { + return SFU_SUCCESS; + } + else + { + return SFU_ERROR; + } +} +#endif /* SFU_MPU_PROTECT_ENABLE */ + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Check and if not applied apply the Static security protections to + * all the SfuEn Sections in Flash: RDP, WRP, PCRoP. Static security protections + * those protections not impacted by a Reset. They are set using the Option Bytes + * When the device is locked (RDP Level2), these protections cannot be changed anymore + * @param None + * @note By default, the best security protections are applied to the different + * flash sections in order to maximize the security level for the specific MCU. + * @retval uint32_t CRC (returned value is the combination of all the applied protections. + * If different from SFU_STD_PROTECTION_ALL, 1 or more protections cannot be applied) + */ +SFU_ErrorStatus SFU_LL_SECU_CheckApplyStaticProtections(void) +{ + FLASH_OBProgramInitTypeDef flash_option_bytes; + SFU_BoolTypeDef is_protection_to_be_applied = SFU_FALSE; + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + uint32_t i_protection_set = 0U; + uint32_t i_ctrl = 0U; + + /* Unlock the Flash to enable the flash control register access *************/ + (void) HAL_FLASH_Unlock(); + + /* Clear OPTVERR bit set on virgin samples */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); + + /* Unlock the Options Bytes *************************************************/ + (void) HAL_FLASH_OB_Unlock(); + + /* Get Option Bytes status for WRP AREA_A **********/ + flash_option_bytes.WRPArea = SFU_PROTECT_WRP_AREA_1; + (void) HAL_FLASHEx_OBGetConfig(&flash_option_bytes); + + /* Check/Apply RDP_Level 1. This is the minimum protection allowed */ + /* if RDP_Level 2 is already applied it's not possible to modify the OptionBytes anymore */ + if (flash_option_bytes.RDPLevel == OB_RDP_LEVEL_2) + { + /* Sanity check of the (enabled) static protections */ + if (SFU_LL_SECU_CheckFlashConfiguration(&flash_option_bytes) != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] Flash configuration failed! Product blocked."); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } + +#ifdef SFU_WRP_PROTECT_ENABLE + if (SFU_LL_SECU_CheckProtectionWRP(&flash_option_bytes) != SFU_SUCCESS) + { + TRACE("\r\n= [SBOOT] System Security Configuration failed! Product blocked."); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); + } +#endif /* SFU_WRP_PROTECT_ENABLE */ + + + + /*RDP level 2 ==> Flow control by-passed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); + } + else + { + /* Check/Set Flash configuration *******************************************/ + if (e_ret_status == SFU_SUCCESS) + { + e_ret_status = SFU_LL_SECU_SetFlashConfiguration(&flash_option_bytes, &is_protection_to_be_applied); + } + i_ctrl++; + + /* Check/Apply WRP ********************************************************/ +#ifdef SFU_WRP_PROTECT_ENABLE + if (e_ret_status == SFU_SUCCESS) + { + i_protection_set++; + e_ret_status = SFU_LL_SECU_SetProtectionWRP(&flash_option_bytes, &is_protection_to_be_applied); + } + i_ctrl++; +#endif /* SFU_WRP_PROTECT_ENABLE */ + + /* Check/Apply PCRoP ******************************************************/ + + + /* Check/Apply RDP : RDP-L2 should be done as last option bytes configuration */ +#ifdef SFU_RDP_PROTECT_ENABLE + if (e_ret_status == SFU_SUCCESS) + { + i_protection_set++; + e_ret_status = SFU_LL_SECU_SetProtectionRDP(&flash_option_bytes, &is_protection_to_be_applied); + } + i_ctrl++; +#endif /* SFU_RDP_PROTECT_ENABLE */ + + if (e_ret_status == SFU_SUCCESS) + { + i_protection_set++; + if (is_protection_to_be_applied) + { + /* Generate System Reset to reload the new option byte values *************/ + /* WARNING: This means that if a protection can't be set, there will be a reset loop! */ + (void) HAL_FLASH_OB_Launch(); + } + } + } + + if (i_protection_set != i_ctrl) + { + e_ret_status = SFU_ERROR; + } + + /* Lock the Options Bytes ***************************************************/ + (void) HAL_FLASH_OB_Lock(); + + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + (void) HAL_FLASH_Lock(); + + /* If it was not possible to apply one of the above mandatory protections, the + Option bytes have not been reloaded. Return the error status in order for the + caller function to take the right actions */ + return e_ret_status; + +} + +/** + * @brief Apply Runtime security protections. + * Runtime security protections have to be re-configured at each Reset. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_CheckApplyRuntimeProtections(uint8_t uStep) +{ + SFU_ErrorStatus e_ret_status = SFU_SUCCESS; + SFU_ProtectionTypeDef runtime_protection = SFU_PROTECTIONS_NONE; + uint32_t i_protection_set = 0U; + uint32_t i_ctrl = 0U; + + /* Depending on compilation switches, prevent compilation warning */ + UNUSED(runtime_protection); + + +#ifdef SFU_MPU_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionMPU(uStep) == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_MPU; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_MPU_PROTECT_ENABLE */ + + + + /* Check/Apply disable DMAs ************************************************/ +#ifdef SFU_DMA_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionDMA() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_DMA; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_DMA_PROTECT_ENABLE */ + + /* Check/Apply IWDG **************************************************/ +#ifdef SFU_IWDG_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionIWDG() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_IWDG; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_IWDG_PROTECT_ENABLE */ + + /* Check/Apply DAP *********************************************************/ +#ifdef SFU_DAP_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionDAP() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_DAP; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#else +#endif /* SFU_DAP_PROTECT_ENABLE */ + + /* Check/Apply ANTI_TAMPER *************************************************/ +#ifdef SFU_TAMPER_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionANTI_TAMPER() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_ANTI_TAMPER; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#else +#ifdef SFU_TEST_PROTECTION + if (SFU_LL_RTC_Init() != SFU_SUCCESS) + { + e_ret_status = SFU_ERROR; + } +#endif /* SFU_TEST_PROTECTION */ +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + /* Check/Apply CLOCK_MONITOR **********************************************/ +#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionCLOCK_MONITOR() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_CLOCK_MONITOR; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_CLCK_MNTR_PROTECT_ENABLE */ + + /* Check/Apply TEMP_MONITOR **********************************************/ +#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE + if (SFU_LL_SECU_SetProtectionTEMP_MONITOR() == SFU_SUCCESS) + { + runtime_protection |= SFU_RUNTIME_PROTECTION_TEMP_MONITOR; + i_protection_set++; + } + else + { + /* When a protection cannot be set then SFU_ERROR is returned */ + e_ret_status = SFU_ERROR; + } + i_ctrl++; +#endif /* SFU_TEMP_MNTR_PROTECT_ENABLE */ + +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n= [SBOOT] RuntimeProtections: %x", runtime_protection); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + if (i_protection_set != i_ctrl) + { + e_ret_status = SFU_ERROR; + } + + return e_ret_status; +} + +/** + * @brief Return the reset source detected after a reboot. The related flag is reset + * at the end of this function. + * @param peResetpSourceId: to be filled with the detected source of reset + * @note In case of multiple reset sources this function return only one of them. + * It can be improved returning and managing a combination of them. + * @retval SFU_SUCCESS if successful, SFU_ERROR otherwise + */ +void SFU_LL_SECU_GetResetSources(SFU_RESET_IdTypeDef *peResetpSourceId) +{ + /* Check if the last reset has been generated from a Watchdog exception */ + if ((__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) || + (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)) + { + *peResetpSourceId = SFU_RESET_WDG_RESET; + + } + + + /* Check if the last reset has been generated from a Low Power reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) != RESET) + { + *peResetpSourceId = SFU_RESET_LOW_POWER; + + } + + /* Check if the last reset has been generated from a Software reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) != RESET) + { + *peResetpSourceId = SFU_RESET_SW_RESET; + + } + /* Check if the last reset has been generated from an Option Byte Loader reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST) != RESET) + { + *peResetpSourceId = SFU_RESET_OB_LOADER; + } + /* Check if the last reset has been generated from a Hw pin reset */ + else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET) + { + *peResetpSourceId = SFU_RESET_HW_RESET; + + } + /* Unknown */ + else + { + *peResetpSourceId = SFU_RESET_UNKNOWN; + } +} + +/** + * @brief Clear the reset sources. This function should be called after the actions + * on the reset sources has been already taken. + * @param none + * @note none + * @retval none + */ +void SFU_LL_SECU_ClearResetSources() +{ + /* Clear reset flags */ + __HAL_RCC_CLEAR_RESET_FLAGS(); +} + +/** + * @brief Refresh Watchdog : reload counter + * This function must be called just before jumping to the UserFirmware + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_IWDG_Refresh(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + +#ifdef SFU_IWDG_PROTECT_ENABLE + /* Refresh IWDG: reload counter */ + if (HAL_IWDG_Refresh(&IwdgHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + } +#else + e_ret_status = SFU_SUCCESS; +#endif /*SFU_IWDG_PROTECT_ENABLE*/ + + return e_ret_status; +} + +/** + * @brief Check Flash configuration. + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @retval SFU_ErrorStatus SFU_SUCCESS if Flash configuration is correct, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_CheckFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check/Apply BOOT_LOCK ****************************************************/ + if ((psFlashOptionBytes->UserConfig & FLASH_OPTR_BOOT_LOCK) == OB_BOOT_LOCK_ENABLE) + { + e_ret_status = SFU_SUCCESS; + } + if (e_ret_status == SFU_SUCCESS) + { + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_UBE, FLOW_CTRL_UBE); + } + return e_ret_status; + +} + +/** + * @brief Set Flash configuration. + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if + * this OptByte has to be modified and immediately reloaded. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetFlashConfiguration(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check Flash configuration */ + if (SFU_LL_SECU_CheckFlashConfiguration(psFlashOptionBytes) == SFU_SUCCESS) + { + e_ret_status = SFU_SUCCESS; + } + else + { +#if defined(SECBOOT_OB_DEV_MODE) + psFlashOptionBytes->OptionType = OPTIONBYTE_USER; + psFlashOptionBytes->UserConfig &= ~OB_BOOT_LOCK_ENABLE; + psFlashOptionBytes->UserConfig |= OB_BOOT_LOCK_ENABLE; + if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) + { + *pbIsProtectionToBeApplied |= 1U; + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_UBE, FLOW_CTRL_UBE); + } +#else + TRACE("\r\n= [SBOOT] Boot Configuration issue: booting Main flash through PA14-BOOT0 pin functionality cannot be guaranteed"); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); +#endif /* SECBOOT_OB_DEV_MODE */ + } + + return e_ret_status; +} + +#ifdef SFU_RDP_PROTECT_ENABLE +/** + * @brief Apply the RDP protection + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if + * this OptByte has to be modified and immediately reloaded. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionRDP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check/Apply RDP **********************************************************/ + /* Please consider that the suggested and most secure approach is to set the RDP_LEVEL_2 */ + if (psFlashOptionBytes->RDPLevel == SFU_PROTECT_RDP_LEVEL) + { + e_ret_status = SFU_SUCCESS; /*Protection already applied */ + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); + } + else + { +#if defined(SECBOOT_OB_DEV_MODE) +#if defined(SFU_FINAL_SECURE_LOCK_ENABLE) + TRACE("\r\n\t Applying RDP-2 Level. Product locked! You might need to unplug/plug the USB cable!"); +#else + TRACE("\r\n\t Applying RDP-1 Level. You might need to unplug/plug the USB cable!"); +#endif /* SFU_FINAL_SECURE_LOCK_ENABLE */ + psFlashOptionBytes->OptionType = OPTIONBYTE_RDP; + psFlashOptionBytes->RDPLevel = SFU_PROTECT_RDP_LEVEL; + if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) + { + *pbIsProtectionToBeApplied |= 1U; + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_RDP, FLOW_CTRL_RDP); + } +#else + TRACE("\r\n= [SBOOT] System Security Configuration failed: RDP is incorrect. STOP!"); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); +#endif /* SECBOOT_OB_DEV_MODE */ + } + return e_ret_status; +} +#endif /*SFU_RDP_PROTECT_ENABLE*/ + +#ifdef SFU_WRP_PROTECT_ENABLE +/** + * @brief Check the WRP protection to the specified Area. It includes the SFU Vector Table + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_CheckProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check WRP ****************************************************************/ + if ((psFlashOptionBytes->WRPStartOffset == SFU_PROTECT_WRP_PAGE_START_1) && + (psFlashOptionBytes->WRPEndOffset == SFU_PROTECT_WRP_PAGE_END_1)) + { + e_ret_status = SFU_SUCCESS; /*Protection applied */ + } + if (e_ret_status == SFU_SUCCESS) + { + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_WRP, FLOW_CTRL_WRP); + } + return e_ret_status; +} + +/** + * @brief Apply the WRP protection to the specified Area. It includes the SFU Vector Table + * @param psFlashOptionBytes: pointer to the Option Bytes structure + * @param pbIsProtectionToBeApplied: Output parameter to be set as "TRUE" if + * this OptByte has to be modified and immediately reloaded. + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionWRP(FLASH_OBProgramInitTypeDef *psFlashOptionBytes, + SFU_BoolTypeDef *pbIsProtectionToBeApplied) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Check/Apply WRP **********************************************************/ + if (SFU_LL_SECU_CheckProtectionWRP(psFlashOptionBytes) == SFU_SUCCESS) + { + e_ret_status = SFU_SUCCESS; /*Protection already applied */ + } + else + { +#if defined(SECBOOT_OB_DEV_MODE) + psFlashOptionBytes->OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes->WRPArea = SFU_PROTECT_WRP_AREA_1; + psFlashOptionBytes->WRPStartOffset = SFU_PROTECT_WRP_PAGE_START_1; + psFlashOptionBytes->WRPEndOffset = SFU_PROTECT_WRP_PAGE_END_1; + + if (HAL_FLASHEx_OBProgram(psFlashOptionBytes) == HAL_OK) + { + *pbIsProtectionToBeApplied |= 1U; + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_WRP, FLOW_CTRL_WRP); + } +#else + TRACE("\r\n= [SBOOT] System Security Configuration failed: WRP is incorrect. STOP!"); + /* Security issue : execution stopped ! */ + SFU_EXCPT_Security_Error(); +#endif /* SECBOOT_OB_DEV_MODE */ + } + + return e_ret_status; +} +#endif /*SFU_WRP_PROTECT_ENABLE*/ + +#ifdef SFU_MPU_PROTECT_ENABLE +/** + * @brief Apply MPU protection before executing UserApp + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU_UserApp(void) +{ + MPU_Region_InitTypeDef MPU_InitStruct; + + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER6; + MPU_InitStruct.BaseAddress = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_START; + MPU_InitStruct.Size = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SIZE; + MPU_InitStruct.SubRegionDisable = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SREG; + MPU_InitStruct.AccessPermission = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_PERM; + MPU_InitStruct.DisableExec = APP_PROTECT_MPU_AREA_ACTIVE_SLOT_EXEC; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER7; + MPU_InitStruct.BaseAddress = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_START; + MPU_InitStruct.Size = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SIZE; + MPU_InitStruct.SubRegionDisable = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SREG; + MPU_InitStruct.AccessPermission = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_PERM; + MPU_InitStruct.DisableExec = APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_EXEC; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + + return SFU_SUCCESS; +} +#endif /* SFU_MPU_PROTECT_ENABLE */ + +#if (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) +/** + * @brief Apply MPU protection before executing Standalone loader + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU_StandaloneLoader(void) +{ + MPU_Region_InitTypeDef MPU_InitStruct; + + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER6; + MPU_InitStruct.BaseAddress = LOADER_PROTECT_MPU_AREA_START; + MPU_InitStruct.Size = LOADER_PROTECT_MPU_AREA_SIZE; + MPU_InitStruct.SubRegionDisable = LOADER_PROTECT_MPU_AREA_SREG; + MPU_InitStruct.AccessPermission = LOADER_PROTECT_MPU_AREA_PERM; + MPU_InitStruct.DisableExec = LOADER_PROTECT_MPU_AREA_EXEC; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + return SFU_SUCCESS; +} +#endif /* (SECBOOT_LOADER == SECBOOT_USE_STANDALONE_LOADER) */ + +#ifdef SFU_MPU_PROTECT_ENABLE + +/** + * @brief Apply MPU protection + * @param uStep Configuration step : SFU_INITIAL_CONFIGURATION, SFU_SECOND_CONFIGURATION, SFU_THIRD_CONFIGURATION + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionMPU(uint8_t uStep) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + uint8_t mpu_region_num; /* id of the MPU region being configured */ + MPU_Region_InitTypeDef MPU_InitStruct; + + + for (mpu_region_num = 0U; mpu_region_num < (sizeof(MpuAreas) / sizeof(SFU_MPU_InitTypeDef)); mpu_region_num++) + { + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MpuAreas[mpu_region_num].Number; + MPU_InitStruct.BaseAddress = MpuAreas[mpu_region_num].BaseAddress; + MPU_InitStruct.Size = MpuAreas[mpu_region_num].Size; + MPU_InitStruct.SubRegionDisable = MpuAreas[mpu_region_num].SubRegionDisable; + MPU_InitStruct.AccessPermission = MpuAreas[mpu_region_num].AccessPermission; + MPU_InitStruct.DisableExec = MpuAreas[mpu_region_num].DisableExec; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE(" @%d:%x size:%x sub:%x perm:%x exec:%x\r\n", + MPU_InitStruct.Number, MPU_InitStruct.BaseAddress, MPU_InitStruct.Size, MPU_InitStruct.SubRegionDisable, + MPU_InitStruct.AccessPermission, MPU_InitStruct.DisableExec); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + + if (uStep == SFU_INITIAL_CONFIGURATION) + { + HAL_MPU_ConfigRegion(&MPU_InitStruct); + } + else + { + if (MPU_CheckConfig(&MPU_InitStruct) == SFU_ERROR) + { + return SFU_ERROR; + } + } + } + + if (uStep == SFU_INITIAL_CONFIGURATION) + { +#if defined(SFU_VERBOSE_DEBUG_MODE) + TRACE("\r\n"); +#endif /* SFU_VERBOSE_DEBUG_MODE */ + /* Enables the MPU */ + HAL_MPU_Enable(MPU_HARDFAULT_NMI); + +#if defined(SCB_SHCSR_MEMFAULTENA_Msk) + /* Enables memory fault exception */ + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif /* SCB_SHCSR_MEMFAULTENA_Msk */ + } + else + { + if (MPU->CTRL != (MPU_HARDFAULT_NMI | MPU_CTRL_ENABLE_Msk)) + { + return SFU_ERROR; + } +#if defined(SCB_SHCSR_MEMFAULTENA_Msk) + if ((SCB->SHCSR & SCB_SHCSR_MEMFAULTENA_Msk) != SCB_SHCSR_MEMFAULTENA_Msk) + { + return SFU_ERROR; + } +#endif /* SCB_SHCSR_MEMFAULTENA_Msk */ + } + + e_ret_status = SFU_SUCCESS; + + + if (e_ret_status == SFU_SUCCESS) + { + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_MPU, FLOW_CTRL_MPU); + } + return e_ret_status; +} +#endif /*SFU_MPU_PROTECT_ENABLE*/ + + + +#ifdef SFU_DMA_PROTECT_ENABLE +/** + * @brief Apply DMA protection + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionDMA(void) +{ + /* + * In this function we disable the DMA buses in order to avoid that while the SB/SFU is running + * some DMA has been already enabled (e.g. through debugger in RDP-1 after reset) in order to access sensitive + * information in SRAM, FLASH + */ + /* Disable DMA1, DMA2 */ + __HAL_RCC_DMA1_CLK_DISABLE(); + + __HAL_RCC_DMA2_CLK_DISABLE(); + + __HAL_RCC_DMAMUX1_CLK_DISABLE(); + + + + + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_DMA, FLOW_CTRL_DMA); + return SFU_SUCCESS; +} +#endif /*SFU_DMA_PROTECT_ENABLE*/ + +#ifdef SFU_IWDG_PROTECT_ENABLE +/** + * @brief Apply IWDG protection + * The IWDG timeout is set to 4 second. + * Then, the IWDG reload counter is configured as below to obtain 4 second according + * to the measured LSI frequency after setting the prescaler value: + * IWDG counter clock Frequency = LSI Frequency / Prescaler value + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionIWDG(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* TIMER could be used to get the LSI frequency in order to have a more precise IWDG. + This is not used in this implementation because not necessary and in order + to optimize code-size. If you are interested, please have a look at the IWDG Cube example. */ + + /* Configure & Start the IWDG peripheral */ + /* Set counter reload value to obtain 6 sec. IWDG TimeOut. + IWDG counter clock Frequency = uwLsiFreq + Set Prescaler to 64 (IWDG_PRESCALER_64) + Timeout Period = (Reload Counter Value * 64) / uwLsiFreq + So Set Reload Counter Value = (6 * uwLsiFreq) / 64 */ + IwdgHandle.Instance = IWDG; + IwdgHandle.Init.Prescaler = IWDG_PRESCALER_64; + IwdgHandle.Init.Reload = (SFU_IWDG_TIMEOUT * LSI_VALUE / 64U); + IwdgHandle.Init.Window = IWDG_WINDOW_DISABLE; + + if (HAL_IWDG_Init(&IwdgHandle) == HAL_OK) + { + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_IWDG, FLOW_CTRL_IWDG); + } + + return e_ret_status; +} +#endif /*SFU_IWDG_PROTECT_ENABLE*/ + +#ifdef SFU_DAP_PROTECT_ENABLE +/** + * @brief Set DAP protection status, configuring SWCLK and SWDIO GPIO pins. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionDAP(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable clock of DBG GPIO port */ + SFU_DBG_CLK_ENABLE(); + + /* Enable the DAP protections, so disable the DAP re-configuring SWCLK and SWDIO GPIO pins */ + GPIO_InitStruct.Pin = SFU_DBG_SWDIO_PIN | SFU_DBG_SWCLK_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(SFU_DBG_PORT, &GPIO_InitStruct); + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_DAP, FLOW_CTRL_DAP); + + return e_ret_status; +} +#else +#endif /*SFU_DAP_PROTECT_ENABLE*/ + +#ifdef SFU_TAMPER_PROTECT_ENABLE +/** + * @brief Apply ANTI TAMPER protection + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionANTI_TAMPER(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + RTC_TamperTypeDef stamperstructure; + + /* RTC_TAMPER_1 (PC13) selected. PA0 connected to RTC_TAMPER_2 is also connected to the B1 button */ + TAMPER_GPIO_CLK_ENABLE(); + + /* Configure Tamper Pin */ + /* tamper is an additional function */ + /* not an alternate Function : config not needed */ + /* Configure the RTC peripheral */ + /* Configure RTC prescaler and RTC data registers */ + /* RTC configured as follows: + - Hour Format = Format 24 + - Asynch Prediv = Value according to source clock + - Synch Prediv = Value according to source clock + - OutPut = Output Disable + - OutPutPolarity = High Polarity + - OutPutType = Open Drain */ + RtcHandle.Instance = RTC; + RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; + RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; + RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; + RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; + RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + + if (HAL_RTC_Init(&RtcHandle) == HAL_OK) + { + /* Configure RTC Tamper */ + stamperstructure.Tamper = RTC_TAMPER_ID; + stamperstructure.Trigger = RTC_TAMPERTRIGGER_FALLINGEDGE; + stamperstructure.Filter = RTC_TAMPERFILTER_DISABLE; + stamperstructure.SamplingFrequency = RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768; + stamperstructure.PrechargeDuration = RTC_TAMPERPRECHARGEDURATION_1RTCCLK; + stamperstructure.TamperPullUp = RTC_TAMPER_PULLUP_ENABLE; + stamperstructure.TimeStampOnTamperDetection = RTC_TIMESTAMPONTAMPERDETECTION_DISABLE; + stamperstructure.NoErase = RTC_TAMPER_ERASE_BACKUP_ENABLE; + stamperstructure.MaskFlag = RTC_TAMPERMASK_FLAG_DISABLE; + + if (HAL_RTCEx_SetTamper_IT(&RtcHandle, &stamperstructure) == HAL_OK) + { + + /* Clear the Tamper interrupt pending bit */ + __HAL_RTC_TAMPER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_TAMP_1); + e_ret_status = SFU_SUCCESS; + /* Execution stopped if flow control failed */ + FLOW_CONTROL_STEP(uFlowProtectValue, FLOW_STEP_TAMPER, FLOW_CTRL_TAMPER); + } + } + + return e_ret_status; +} +#endif /*SFU_TAMPER_PROTECT_ENABLE*/ + +#ifdef SFU_CLCK_MNTR_PROTECT_ENABLE +/** + * @brief Apply CLOCK MONITOR protection + * @note This function has been added just as template to be used/customized + * if a clock monitor is requested. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionCLOCK_MONITOR(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Apply the Clock Monitoring */ + /* Add your code here for customization + e.g. if HSE or LSE is used enable the CSS! + ... + ... + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} +#endif /*SFU_CLCK_MNTR_PROTECT_ENABLE*/ + +#ifdef SFU_TEMP_MNTR_PROTECT_ENABLE +/** + * @brief Apply TEMP MONITOR protection + * @note This function has been added just as template to be used/customized + * if a temperature monitor is requested. + * @param None + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SFU_ErrorStatus SFU_LL_SECU_SetProtectionTEMP_MONITOR(void) +{ + SFU_ErrorStatus e_ret_status = SFU_ERROR; + + /* Apply the Temperature Monitoring */ + /* Add your code here for customization + ... + ... + */ + + e_ret_status = SFU_SUCCESS; + + return e_ret_status; +} +#endif /*SFU_TEMP_MNTR_PROTECT_ENABLE*/ + + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_security.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_security.h new file mode 100644 index 00000000..0a412500 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/BFU/Target/sfu_low_level_security.h @@ -0,0 +1,273 @@ +/** + ****************************************************************************** + * @file sfu_low_level_security.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Firmware Update security + * low level interface. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SFU_LOW_LEVEL_SECURITY_H +#define SFU_LOW_LEVEL_SECURITY_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "sfu_fwimg_regions.h" +#include "sfu_def.h" + +/* Exported constants --------------------------------------------------------*/ + +/*!< Bank 1, Area A used to protect Vector Table */ +#define SFU_PROTECT_WRP_AREA_1 (OB_WRPAREA_BANK1_AREAA) + +/*!< First page including the Vector Table: 0 based */ +#define SFU_PROTECT_WRP_PAGE_START_1 ((uint32_t)((SFU_BOOT_BASE_ADDR - FLASH_BASE) / FLASH_PAGE_SIZE)) + +/*!< Last page: (code_size-1)/page_size because the page + indexes start from 0 */ +#define SFU_PROTECT_WRP_PAGE_END_1 ((uint32_t)((SFU_ROM_ADDR_END - FLASH_BASE) / FLASH_PAGE_SIZE)) + + + +/** + * @brief The regions can overlap, and can be nested. The region 7 has the highest priority + * and the region 0 has the lowest one and this governs how overlapping the regions behave. + * The priorities are fixed, and cannot be changed. + */ + + +/** + * @brief Region 0 - The Aliases Region and all User Flash & internal RAM. When executing inside SB/SFU by default all + * the Aliases and all the User Flash (used for UserApp1 and UserApp2) area must not be executable, + * but used only to read and write the downloaded code RAM is also not executable. + * From this full Area we'll enable the Execution permission only on the SB/SFU Flash Area. + */ + +#define SFU_PROTECT_MPU_AREA_USER_START ((uint32_t)0x00000000U) +#define SFU_PROTECT_MPU_AREA_USER_SIZE MPU_REGION_SIZE_1GB /*!< up to 0x3FFFFFFF */ +#define SFU_PROTECT_MPU_AREA_USER_PERM MPU_REGION_FULL_ACCESS +#define SFU_PROTECT_MPU_AREA_USER_EXEC MPU_INSTRUCTION_ACCESS_DISABLE +#define SFU_PROTECT_MPU_AREA_USER_SREG 0x00U /*!< All subregions activated */ + +/** + * @brief Region 1 and Region 2 - Enable the execution for SB/SFU Full area (SBSFU + SE + Keys). Inner region inside + * the Region 0 + */ +#define SFU_PROTECT_MPU_MAX_NB_SUBREG (8U) /*!< 8 sub-regions is the maximum */ +#define SFU_PROTECT_MPU_AREA_SFUEN_START_0 FLASH_BASE +#define SFU_PROTECT_MPU_AREA_SFUEN_START_1 0x08010000 +#define SFU_PROTECT_MPU_AREA_SFUEN_SIZE_0 MPU_REGION_SIZE_64KB +#define SFU_PROTECT_MPU_AREA_SFUEN_SIZE_1 MPU_REGION_SIZE_16KB +#define SFU_PROTECT_MPU_AREA_SFUEN_PERM MPU_REGION_FULL_ACCESS +#define SFU_PROTECT_MPU_AREA_SFUEN_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#define SFU_PROTECT_MPU_AREA_SFUEN_SREG_0 0x00U /*!< All subregions activated */ +#define SFU_PROTECT_MPU_AREA_SFUEN_SREG_1 0xC0U /*!< 16 bytes / 8 * 6 ==> 12 bytes */ + +/** + * @brief Region 3 - Vector Table: Vector Table must be Read-Only under privileged access. Inner region inside the + * Region 1 + */ +#define SFU_PROTECT_MPU_AREA_VECT_START ((uint32_t) INTVECT_START) /*!< Vector table memory area */ +#define SFU_PROTECT_MPU_AREA_VECT_SIZE MPU_REGION_SIZE_512B +#define SFU_PROTECT_MPU_AREA_VECT_PERM MPU_REGION_PRIV_RO +#define SFU_PROTECT_MPU_AREA_VECT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#define SFU_PROTECT_MPU_AREA_VECT_SREG 0x00U /*!< All subregions activated */ + +/** + * @brief Region 4 - Inner region inside the Region 0 . The Option Bytes. Once the Option Bytes have been set, + * only reading will be possible + */ + +/* + * WLxx + * Single Bank + * [ 1FFF7800 1FFF7808 1FFF7810 1FFF7818 1FFF7820]: 40 bytes to be protected + * The MPU can be used to protect up to eight memory regions. + * These, in turn can have eight subregions, if the region is at least 256 bytes. + * Here, we define a 64B region so subregions cannot be used. + */ +#define SFU_PROTECT_MPU_AREA_OB_BANK1_START ((uint32_t)0x1FFF7800U) /*!< Option Bytes in bank 1 */ +#define SFU_PROTECT_MPU_AREA_OB_BANK1_SIZE MPU_REGION_SIZE_64B /*!< Protecting more than required */ +#define SFU_PROTECT_MPU_AREA_OB_BANK1_PERM MPU_REGION_NO_ACCESS +#define SFU_PROTECT_MPU_AREA_OB_BANK1_EXEC MPU_INSTRUCTION_ACCESS_DISABLE +#define SFU_PROTECT_MPU_AREA_OB_BANK1_SREG 0x00U /*!< Subregion mask to deactivate unexpected + MPU subregions: 0x1F should be set but it + would have no effect as we have a 64B + region */ + +/** + * @brief Region 5 - Peripherals Area + */ +#define SFU_PROTECT_MPU_AREA_PERIPH_START PERIPH_BASE /*!< Peripheral memory area */ +#define SFU_PROTECT_MPU_AREA_PERIPH_SIZE MPU_REGION_SIZE_512MB /*!< To be coherent with the peripherals + memory area */ +#define SFU_PROTECT_MPU_AREA_PERIPH_PERM MPU_REGION_FULL_ACCESS +#define SFU_PROTECT_MPU_AREA_PERIPH_EXEC MPU_INSTRUCTION_ACCESS_DISABLE +#define SFU_PROTECT_MPU_AREA_PERIPH_SREG 0x00U /*!< All subregions activated */ + + +/** + * MPU configuration for UserApp execution + * ======================================= + * @brief Region 6 & 7 - Enable the execution of the active slots + * MPU constraint = Region base address should be aligned on Region size + */ +/** + * Region definition : from 0x0802 B000 ==> 0x0802 BFFF (4 kbytes) + */ +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_START SLOT_ACTIVE_1_START +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SIZE MPU_REGION_SIZE_4KB +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_PERM MPU_REGION_FULL_ACCESS +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#define APP_PROTECT_MPU_AREA_ACTIVE_SLOT_SREG 0x00U /*!< All subregions activated */ +/** + * Additional Region definition : from 0x0802 C000 ==> 0x0803 FFFF (80 kbytes) + */ +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_START 0x08020000 +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SIZE MPU_REGION_SIZE_128KB +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_PERM MPU_REGION_FULL_ACCESS +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_EXEC MPU_INSTRUCTION_ACCESS_ENABLE +#define APP_PROTECT_MPU_AREA_2_ACTIVE_SLOT_SREG 0x07U /*!< 128 Kbytes / 8 * 5 ==> 80 Kbytes */ + + +/** + * @} + */ + +/** @defgroup SFU_CONFIG_TAMPER Tamper Configuration + * @{ + */ +#define TAMPER_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define RTC_TAMPER_ID RTC_TAMPER_1 +#define RTC_TAMPER_ID_INTERRUPT RTC_IT_TAMP_1 + +/** + * @} + */ + +/** @defgroup SFU_CONFIG_DBG Debug Port Configuration + * @{ + */ +#define SFU_DBG_PORT GPIOA +#define SFU_DBG_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_DBG_SWDIO_PIN GPIO_PIN_13 +#define SFU_DBG_SWCLK_PIN GPIO_PIN_14 + + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SFU_SECURITY_Exported_Constants Exported Constants + * @{ + */ + +/** @defgroup SFU_SECURITY_Exported_Constants_Wakeup FU WAKEUP ID Type definition + * @{ + */ +typedef enum +{ + SFU_RESET_UNKNOWN = 0x00U, + SFU_RESET_WDG_RESET, + SFU_RESET_LOW_POWER, + SFU_RESET_HW_RESET, + SFU_RESET_BOR_RESET, + SFU_RESET_SW_RESET, + SFU_RESET_OB_LOADER, +} SFU_RESET_IdTypeDef; + +/** + * @} + */ + +/** @defgroup SFU_SECURITY_Exported_Constants_Protections FU SECURITY Protections_Constants + * @{ + */ +#define SFU_PROTECTIONS_NONE ((uint32_t)0x00000000U) /*!< Protection configuration unchanged */ +#define SFU_STATIC_PROTECTION_RDP ((uint32_t)0x00000001U) /*!< RDP protection level 1 is applied */ +#define SFU_STATIC_PROTECTION_WRP ((uint32_t)0x00000002U) /*!< Constants section in Flash. Needed as + separate section to support PCRoP */ +#define SFU_STATIC_PROTECTION_PCROP ((uint32_t)0x00000004U) /*!< SFU App section in Flash */ +#define SFU_STATIC_PROTECTION_LOCKED ((uint32_t)0x00000008U) /*!< RDP Level2 is applied. The device is Locked! + Std Protections cannot be + added/removed/modified */ +#define SFU_STATIC_PROTECTION_BFB2 ((uint32_t)0x00000010U) /*!< BFB2 is disabled. The device shall always + boot in bank1! */ + +#define SFU_RUNTIME_PROTECTION_MPU ((uint32_t)0x00000100U) /*!< Shared Info section in Flash */ +#define SFU_RUNTIME_PROTECTION_IWDG ((uint32_t)0x00000400U) /*!< Independent Watchdog */ +#define SFU_RUNTIME_PROTECTION_DAP ((uint32_t)0x00000800U) /*!< Debug Access Port control */ +#define SFU_RUNTIME_PROTECTION_DMA ((uint32_t)0x00001000U) /*!< DMA protection, disable DMAs */ +#define SFU_RUNTIME_PROTECTION_ANTI_TAMPER ((uint32_t)0x00002000U) /*!< Anti-Tampering protections */ +#define SFU_RUNTIME_PROTECTION_CLOCK_MONITOR ((uint32_t)0x00004000U) /*!< Activate a clock monitoring */ +#define SFU_RUNTIME_PROTECTION_TEMP_MONITOR ((uint32_t)0x00008000U) /*!< Activate a Temperature monitoring */ + +#define SFU_STATIC_PROTECTION_ALL (SFU_STATIC_PROTECTION_RDP | SFU_STATIC_PROTECTION_WRP | \ + SFU_STATIC_PROTECTION_PCROP | SFU_STATIC_PROTECTION_LOCKED) +/*!< All the static protections */ + +#define SFU_RUNTIME_PROTECTION_ALL (SFU_RUNTIME_PROTECTION_MPU | SFU_RUNTIME_PROTECTION_FWALL | \ + SFU_RUNTIME_PROTECTION_IWDG | SFU_RUNTIME_PROTECTION_DAP | \ + SFU_RUNTIME_PROTECTION_DMA | SFU_RUNTIME_PROTECTION_ANTI_TAMPER | \ + SFU_RUNTIME_PROTECTION_CLOCK_MONITOR | SFU_RUNTIME_PROTECTION_TEMP_MONITOR) +/*!< All the run-time protections */ + +#define SFU_INITIAL_CONFIGURATION (0x00U) /*!< Initial configuration */ +#define SFU_SECOND_CONFIGURATION (0x01U) /*!< Second configuration */ +#define SFU_THIRD_CONFIGURATION (0x02U) /*!< Third configuration */ + +/* Exported functions ------------------------------------------------------- */ +#define SFU_CALLBACK_ANTITAMPER HAL_RTCEx_Tamper1EventCallback +/*!
      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.
      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_HW_H +#define APP_HW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported macros -----------------------------------------------------------*/ +/* At power-on, the capacitor related to SW1 button needs to charge. + * The charging time must be waited to be sure that a low level is a real one. */ +#define BUTTON_INIT() \ + BSP_PB_Init(BUTTON_SW1,BUTTON_MODE_GPIO); \ + if ((uint32_t) BSP_PB_GetState(BUTTON_SW1) == (uint32_t)GPIO_PIN_RESET) \ + { \ + HAL_Delay(6U); \ + } + +#define BUTTON_PUSHED() ((uint32_t) BSP_PB_GetState(BUTTON_SW1) == (uint32_t)GPIO_PIN_RESET) + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_HW_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/Core/Inc/main.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/main.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SBSFU/CM0PLUS/Core/Inc/main.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/main.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h new file mode 100644 index 00000000..df90b1f3 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h @@ -0,0 +1,340 @@ +/** + ****************************************************************************** + * @file stm32wlxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLxx_HAL_CONF_H +#define STM32WLxx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_COMP_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_GTZC_MODULE_ENABLED */ +/* #define HAL_HSEM_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IPCC_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +#define HAL_IWDG_MODULE_ENABLED +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_PKA_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_SUBGHZ_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_EXTI_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED + +/* ########################## Register Callbacks selection ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0u +#define USE_HAL_COMP_REGISTER_CALLBACKS 0u +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u +#define USE_HAL_DAC_REGISTER_CALLBACKS 0u +#define USE_HAL_I2C_REGISTER_CALLBACKS 0u +#define USE_HAL_I2S_REGISTER_CALLBACKS 0u +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u +#define USE_HAL_PKA_REGISTER_CALLBACKS 0u +#define USE_HAL_RNG_REGISTER_CALLBACKS 0u +#define USE_HAL_RTC_REGISTER_CALLBACKS 0u +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u +#define USE_HAL_SPI_REGISTER_CALLBACKS 0u +#define USE_HAL_SUBGHZ_REGISTER_CALLBACKS 0u +#define USE_HAL_TIM_REGISTER_CALLBACKS 0u +#define USE_HAL_UART_REGISTER_CALLBACKS 0u +#define USE_HAL_USART_REGISTER_CALLBACKS 0u +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ + +#if !defined (HSE_VALUE) +#define HSE_VALUE 32000000UL /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) +#define MSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @brief Internal Multiple Speed oscillator (HSI48) default value. + * This value is the default HSI48 range value after Reset. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE 48000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI48_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((1uL <<__NVIC_PRIO_BITS) - 1uL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 1U + +/* ################## CRYP peripheral configuration ########################## */ + +#define USE_HAL_CRYP_SUSPEND_RESUME 1U + + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32wlxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32wlxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32wlxx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32wlxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32wlxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32wlxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32wlxx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32wlxx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32wlxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32wlxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED + #include "stm32wlxx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED + #include "stm32wlxx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32wlxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32wlxx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IPCC_MODULE_ENABLED + #include "stm32wlxx_hal_ipcc.h" +#endif /* HAL_IPCC_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32wlxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32wlxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32wlxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32wlxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32wlxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32wlxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32wlxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32wlxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32wlxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32wlxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32wlxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SUBGHZ_MODULE_ENABLED + #include "stm32wlxx_hal_subghz.h" +#endif /* HAL_SUBGHZ_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32wlxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32wlxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32wlxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32wlxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLxx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_it.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_it.h new file mode 100644 index 00000000..209c9d61 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_it.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * @file stm32wlxx_it.h + * @author MCD Application Team + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLxx_IT_H +#define STM32WLxx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wlxx_hal.h" + +/* External variables --------------------------------------------------------*/ +extern RTC_HandleTypeDef RtcHandle; + +/* Exported functions ------------------------------------------------------- */ +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +#ifdef SFU_TAMPER_PROTECT_ENABLE +void TAMP_STAMP_LSECSS_SSRU_IRQHandler(void); +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLxx_IT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h new file mode 100644 index 00000000..0af7b23e --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * @file stm32wlxx_nucleo_conf.h + * @author MCD Application Team + * @brief STM32WLxx_Nucleo board configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2020(-2021) STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLXX_NUCLEO_CONF_H +#define STM32WLXX_NUCLEO_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wlxx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WLXX_NUCLEO + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG CONFIG + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG_Exported_Constants Exported Constants + * @{ + */ +/* COM usage define */ +#define USE_BSP_COM_FEATURE 0U + +/* COM log define */ +#define USE_COM_LOG 0U + +/* IRQ priorities */ +#define BSP_BUTTON_SWx_IT_PRIORITY 15U + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLXX_NUCLEO_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/main.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/main.c new file mode 100644 index 00000000..d2bf7435 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/main.c @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * @file main.c + * @author MCD Application Team + * @brief Main application file. + * This application demonstrates Secure Boot and Secure Firmware Update. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_boot.h" + + +/* Private variables ---------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief main function + * @param None + * @retval int + */ +int main(void) +{ + + /* MCU Configuration--------------------------------------------------------*/ + /* This part is NOT secure (security mechanisms NOT enabled yet) */ + /* Reset of all peripherals, Initializes the Flash interface and the Systick*/ + (void) HAL_Init(); + + /* Configure the system clock */ + SystemClock_Config(); + + /* Board BSP Configuration-------------------------------------------------*/ + /* + * As the secure mode has not been entered yet, we do not configure BSP right now . + * The BSP will be configured by the bootloader. + */ + + + /* Launch the Bootloader----------------------------------------------------*/ + /* + * This is the beginning of the secure part: + * security mechanisms will be enabled. + * The function below should not return (unless a critical failure is encountered). + */ + (void)SFU_BOOT_RunSecureBootService(); /* no need to take care of the returned value as we reboot in all cases */ + + /* Security or SecureBoot initialization failure. Force a System Reset */ + SFU_BOOT_ForceReboot(); + +} + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSI) + * SYSCLK(Hz) = 48000000 + * HCLK(Hz) = 48000000 + * HCLK1 Prescaler = 1 + * HCKL2 Prescaler = 1 + * HCKL3 Prescaler = 1 + * APB1 Prescaler = 1 + * APB2 Prescaler = 1 + * HSI Frequency(Hz) = 16000000 + * PLL_M = 2 //not considered on FPGA as VCO output is fixed at 240Mhz + * PLL_N = 30 //not considered on FPGA as VCO output is fixed at 240Mhz + * PLL_N = 20 //Allow to fix VCO to 160Mhz, and reach Sysclk Max Frqe = 32MHz + * with PLL_DIV5 + * PLL_P = 5 + * PLL_Q = 5 + * PLL_R = 5 + * Flash Latency(WS) = 2 + * @param None + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + /* Activate PLL with HSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.HSICalibrationValue = 70; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2; + RCC_OscInitStruct.PLL.PLLN = 20; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV5; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV5; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + /* Initialization Error */ + while (1); + } + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2\ + | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK3); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1; + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + /* Initialization Error */ + while (1); + } +} + + + + + +#ifdef USE_FULL_ASSERT + +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ + +} + +#endif /* USE_FULL_ASSERT */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c new file mode 100644 index 00000000..fb0c4eda --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c @@ -0,0 +1,92 @@ +/** + ****************************************************************************** + * @file stm32wlxx_hal_msp.c + * @author MCD Application Team + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "sfu_low_level.h" + +/* Functions Definition ------------------------------------------------------*/ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + + /* System interrupt init*/ + /* MemoryManagement_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0U, 0U); + /* BusFault_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(BusFault_IRQn, 0U, 0U); + /* UsageFault_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(UsageFault_IRQn, 0U, 0U); + /* DebugMonitor_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0U, 0U); + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0U, 0U); + +} + +/** + * @brief RTC MSP Initialization + * This function configures the hardware resources used in this example + * @param hrtc: RTC handle pointer + * @retval None + */ +void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) +{ + SFU_LL_RTC_MspInit(hrtc); +} + +/** + * @brief RTC MSP De-Initialization + * This function frees the hardware resources used in this example. + * @param hrtc: RTC handle pointer + * @retval None + */ +void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc) +{ + SFU_LL_RTC_MspDeInit(hrtc); +} + +/** + * @brief UART MSP Initialization + * This function configures the hardware resources used in this example + * @param huart: UART handle pointer + * @retval None + */ +void HAL_UART_MspInit(UART_HandleTypeDef *huart) +{ + SFU_LL_UART_MspInit(huart); +} + +/** + * @brief UART MSP De-Initialization + * This function frees the hardware resources used in this example: + * - Disable the Peripheral's clock + * @param huart: UART handle pointer + * @retval None + */ +void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) +{ + SFU_LL_UART_MspDeInit(huart); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/stm32wlxx_it.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/stm32wlxx_it.c new file mode 100644 index 00000000..b68f7c5a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/Core/Src/stm32wlxx_it.c @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * @file stm32wlxx_it.c + * @author MCD Application Team + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32wlxx_it.h" + +/* Global variables ----------------------------------------------------------*/ +/* RTC handler declaration */ +RTC_HandleTypeDef RtcHandle; + +/* Functions Definition ------------------------------------------------------*/ +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ + +/* Exception handlers are implemented in the various source files of sbsfu application */ + +/* NMI exception handler is implemented in sfu_low_level_flash_int.c file */ +/* Hard Fault exception handler is implemented in sfu_boot.c file */ +/* Memory Manage exception handler is implemented in sfu_boot.c file */ +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +void SVC_Handler(void) +{ +} + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +void PendSV_Handler(void) +{ +} + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +void SysTick_Handler(void) +{ + HAL_IncTick(); +} + +/******************************************************************************/ +/* STM32WLxx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32wlxx.s). */ +/******************************************************************************/ +#ifdef SFU_TAMPER_PROTECT_ENABLE +/** + * @brief This function handles Tamper interrupt request. + * @param None + * @retval None + */ +void TAMP_STAMP_LSECSS_SSRU_IRQHandler() +{ + HAL_RTCEx_TamperIRQHandler(&RtcHandle); +} +#endif /* SFU_TAMPER_PROTECT_ENABLE */ + + + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.ewd new file mode 100644 index 00000000..a98ad64e --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.ewd @@ -0,0 +1,1419 @@ + + + 3 + + STM32WL55JC_Nucleo_1_Image_BFU + + ARM + + 1 + + C-SPY + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.ewp new file mode 100644 index 00000000..b5f1e71d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.ewp @@ -0,0 +1,1229 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_BFU + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + $TOOLKIT_DIR$\bin\isymexport.exe --edit "$PROJ_DIR$\steering_file.txt" "$TARGET_PATH$" "$PROJ_DIR$\se_interface_appli.o" + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + Core + + $PROJ_DIR$\..\Core\Src\main.c + + + $PROJ_DIR$\..\Core\Src\stm32wlxx_hal_msp.c + + + $PROJ_DIR$\..\Core\Src\stm32wlxx_it.c + + + + BFU + + App + + $PROJ_DIR$\..\BFU\App\sfu_loader.c + + + $PROJ_DIR$\..\BFU\App\sfu_boot.c + + + $PROJ_DIR$\..\BFU\App\sfu_com_loader.c + + + $PROJ_DIR$\..\BFU\App\sfu_com_trace.c + + + $PROJ_DIR$\..\BFU\App\sfu_error.c + + + $PROJ_DIR$\..\BFU\App\sfu_test.c + + + $PROJ_DIR$\..\BFU\App\sfu_fwimg_common.c + + + $PROJ_DIR$\..\BFU\App\sfu_fwimg_no_swap.c + + + $PROJ_DIR$\..\BFU\App\sfu_fwimg_swap.c + + + $PROJ_DIR$\..\BFU\App\sfu_new_image.c + + + $PROJ_DIR$\..\BFU\App\sfu_kms.c + + + $PROJ_DIR$\..\BFU\App\sfu_interface_crypto_scheme.c + + + + Target + + $PROJ_DIR$\..\BFU\Target\sfu_low_level.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash_int.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_flash_ext.c + + + $PROJ_DIR$\..\BFU\Target\sfu_low_level_security.c + + + + + EWARM + + $PROJ_DIR$\startup_stm32wl55xx_cm4.s + + + + + Drivers + + BSP + + STM32WLxx_Nucleo + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\BSP\STM32WLxx_Nucleo\stm32wlxx_nucleo.c + + + + + STM32WLxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cortex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_iwdg.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_exti.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c + + + + CMSIS + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\CMSIS\Device\ST\STM32WLxx\Source\Templates\system_stm32wlxx.c + + + + + Middlewares + + STM32_Secure_Engine + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_application.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_bootloader.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_interface_common.c + + + + STM32_Key_Management_Services + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\iKMS\se_interface_kms.c + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s new file mode 100644 index 00000000..658ca8e5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/startup_stm32wl55xx_cm4.s @@ -0,0 +1,509 @@ +;******************************************************************************** +;* File Name : startup_stm32wl55xx_cm4.s +;* Author : MCD Application Team +;* Description : M4 core vector table of the STM32WLxxxx devices for the +;* IAR (EWARM) toolchain. +;* +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* +;* Copyright (c) 2020(2021) STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +; +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD and PVM Interrupt + DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSRU Interrupts + DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt + DCD FLASH_IRQHandler ; FLASH global Interrupt + DCD RCC_IRQHandler ; RCC Interrupt + DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt + DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt + DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt + DCD EXTI3_IRQHandler ; EXTI Line 3 Interrupt + DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt + DCD ADC_IRQHandler ; ADC Interrupt + DCD DAC_IRQHandler ; DAC Interrupt + DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV Interrupt + DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts + DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt + DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt + DCD TIM2_IRQHandler ; TIM2 Global Interrupt + DCD TIM16_IRQHandler ; TIM16 Global Interrupt + DCD TIM17_IRQHandler ; TIM17 Global Interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt + DCD SPI1_IRQHandler ; SPI1 Interrupt + DCD SPI2_IRQHandler ; SPI2 Interrupt + DCD USART1_IRQHandler ; USART1 Interrupt + DCD USART2_IRQHandler ; USART2 Interrupt + DCD LPUART1_IRQHandler ; LPUART1 Interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 Global Interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 Global Interrupt + DCD EXTI15_10_IRQHandler ; EXTI Lines [15:10] Interrupt + DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 Global Interrupt + DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt + DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt + DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt + DCD HSEM_IRQHandler ; HSEM0 Interrupt + DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt + DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt + DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt + DCD AES_IRQHandler ; AES Interrupt + DCD RNG_IRQHandler ; RNG1 Interrupt + DCD PKA_IRQHandler ; PKA Interrupt + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt + DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_PVM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_PVM_IRQHandler + B PVD_PVM_IRQHandler + + PUBWEAK TAMP_STAMP_LSECSS_SSRU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_STAMP_LSECSS_SSRU_IRQHandler + B TAMP_STAMP_LSECSS_SSRU_IRQHandler + + PUBWEAK RTC_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_WKUP_IRQHandler + B RTC_WKUP_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel2_IRQHandler + B DMA1_Channel2_IRQHandler + + PUBWEAK DMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel3_IRQHandler + B DMA1_Channel3_IRQHandler + + PUBWEAK DMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel4_IRQHandler + B DMA1_Channel4_IRQHandler + + PUBWEAK DMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel5_IRQHandler + B DMA1_Channel5_IRQHandler + + PUBWEAK DMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel6_IRQHandler + B DMA1_Channel6_IRQHandler + + PUBWEAK DMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel7_IRQHandler + B DMA1_Channel7_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK DAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC_IRQHandler + B DAC_IRQHandler + + PUBWEAK C2SEV_PWR_C2H_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +C2SEV_PWR_C2H_IRQHandler + B C2SEV_PWR_C2H_IRQHandler + + PUBWEAK COMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP_IRQHandler + B COMP_IRQHandler + + PUBWEAK EXTI9_5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_5_IRQHandler + B EXTI9_5_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK EXTI15_10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_10_IRQHandler + B EXTI15_10_IRQHandler + + PUBWEAK RTC_Alarm_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Alarm_IRQHandler + B RTC_Alarm_IRQHandler + + PUBWEAK LPTIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM3_IRQHandler + B LPTIM3_IRQHandler + + PUBWEAK SUBGHZSPI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZSPI_IRQHandler + B SUBGHZSPI_IRQHandler + + PUBWEAK IPCC_C1_RX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_RX_IRQHandler + B IPCC_C1_RX_IRQHandler + + PUBWEAK IPCC_C1_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_TX_IRQHandler + B IPCC_C1_TX_IRQHandler + + PUBWEAK HSEM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HSEM_IRQHandler + B HSEM_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK SUBGHZ_Radio_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZ_Radio_IRQHandler + B SUBGHZ_Radio_IRQHandler + + PUBWEAK AES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AES_IRQHandler + B AES_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK PKA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PKA_IRQHandler + B PKA_IRQHandler + + PUBWEAK DMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel1_IRQHandler + B DMA2_Channel1_IRQHandler + + PUBWEAK DMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel2_IRQHandler + B DMA2_Channel2_IRQHandler + + PUBWEAK DMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel3_IRQHandler + B DMA2_Channel3_IRQHandler + + PUBWEAK DMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel4_IRQHandler + B DMA2_Channel4_IRQHandler + + PUBWEAK DMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel5_IRQHandler + B DMA2_Channel5_IRQHandler + + PUBWEAK DMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel6_IRQHandler + B DMA2_Channel6_IRQHandler + + PUBWEAK DMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel7_IRQHandler + B DMA2_Channel7_IRQHandler + + PUBWEAK DMAMUX1_OVR_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMAMUX1_OVR_IRQHandler + B DMAMUX1_OVR_IRQHandler + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/steering_file.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/steering_file.txt new file mode 100644 index 00000000..8349caff --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/steering_file.txt @@ -0,0 +1,37 @@ +show SE_APP_GetActiveFwInfo +show SE_KMS_Initialize +show SE_KMS_Finalize +show SE_KMS_GetInfo +show SE_KMS_GetFunctionList +show SE_KMS_GetSlotList +show SE_KMS_GetSlotInfo +show SE_KMS_GetTokenInfo +show SE_KMS_GetMechanismInfo +show SE_KMS_OpenSession +show SE_KMS_CloseSession +show SE_KMS_CreateObject +show SE_KMS_DestroyObject +show SE_KMS_GetAttributeValue +show SE_KMS_SetAttributeValue +show SE_KMS_FindObjectsInit +show SE_KMS_FindObjects +show SE_KMS_FindObjectsFinal +show SE_KMS_EncryptInit +show SE_KMS_Encrypt +show SE_KMS_EncryptUpdate +show SE_KMS_EncryptFinal +show SE_KMS_DecryptInit +show SE_KMS_Decrypt +show SE_KMS_DecryptUpdate +show SE_KMS_DecryptFinal +show SE_KMS_DigestInit +show SE_KMS_Digest +show SE_KMS_DigestUpdate +show SE_KMS_DigestFinal +show SE_KMS_SignInit +show SE_KMS_Sign +show SE_KMS_VerifyInit +show SE_KMS_Verify +show SE_KMS_DeriveKey +show SE_KMS_GenerateKeyPair +show SE_KMS_GenerateRandom diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/stm32wl55xx_flash_cm4.icf new file mode 100644 index 00000000..3aa0929b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/EWARM/stm32wl55xx_flash_cm4.icf @@ -0,0 +1,30 @@ +/*###ICF### Set of symbols used in SE and BFU projects ****/ + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x1A00; +define symbol __ICFEDIT_size_heap__ = 0; + +define memory mem with size = 4G; + +/******************************************************************************/ +/* Include of SE symbols file */ +/* (Project>Options>Linker>Extra Options --config_search option is used to */ +/* specify the the directory to search for include files */ +/******************************************************************************/ +include "mapping_sbsfu.icf"; +include "mapping_fwimg.icf"; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +/******************************************************************************/ +/* placement instructions */ +/******************************************************************************/ +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place at address mem:__ICFEDIT_SE_CallGate_region_ROM_start__ { readonly section SE_CORE_Bin }; +place in SE_IF_ROM_region {section .SE_IF_Code}; +place in SB_ROM_region { readonly }; +place in SB_RAM_region { readwrite, block CSTACK, block HEAP}; diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/BFU.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/BFU.sct new file mode 100644 index 00000000..d5e2d56c --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/BFU.sct @@ -0,0 +1,47 @@ +#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0plus -E -xc +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* +#include "..\..\Linker_Common\MDK-ARM\mapping_sbsfu.h" +#include "..\..\Linker_Common\MDK-ARM\mapping_fwimg.h" + +; *** regions needed by SBSFU project *** +LR_ROM_Vector INTVECT_START VECTOR_SIZE { + vector_start INTVECT_START VECTOR_SIZE { + *.o (RESET, +First) + } +} + +LR_SE SE_CODE_REGION_ROM_START { + SE_CallGate_region_ROM SE_CODE_REGION_ROM_START FIXED { + *(SE_CORE_Bin) + } +} + +LR_IF SE_IF_REGION_ROM_START { + SE_IF_region_ROM SE_IF_REGION_ROM_START FIXED SE_IF_ROM_REGION_SIZE { + se_interface_application.o (+RO) + se_interface_bootloader.o (+RO) + se_interface_common.o (+RO) + se_interface_kms.o (+RO) + } +} + +LR_SB SB_REGION_ROM_START { + SB_region_ROM SB_REGION_ROM_START FIXED SB_ROM_REGION_SIZE { + *(InRoot$$Sections) + .ANY (+RO) + } + + SB_RAM_region SB_REGION_RAM_START SB_RAM_REGION_SIZE { + .ANY (+RW +ZI) + .ANY (STACK) + .ANY (HEAP) + } +} + +LR_KMS_DataStorage KMS_DATASTORAGE_START KMS_DATASTORAGE_SIZE { + ER_KMS_DataStorage KMS_DATASTORAGE_START FILL 0X00000000 KMS_DATASTORAGE_SIZE { + } +} + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/Project.uvoptx new file mode 100644 index 00000000..63eceab2 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/Project.uvoptx @@ -0,0 +1,916 @@ + + + + 1.0 + +
      ### uVision Project, (C) Keil Software
      + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32WL55JC_Nucleo_1_Image_BFU + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ST-LINKIII-KEIL_SWO + -U001F00313038511234333935 -O206 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4.FLM -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + 0 + UL2CM3 + -U -O206 -S0 -C0 -P00 -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + + + + 0 + 1 + e_ret_status + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Application/Core + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ../Core/Src/main.c + main.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ../Core/Src/stm32wlxx_hal_msp.c + stm32wlxx_hal_msp.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ../Core/Src/stm32wlxx_it.c + stm32wlxx_it.c + 0 + 0 + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 2 + 4 + 2 + 0 + 0 + 0 + se_core_bin.s + se_core_bin.s + 0 + 0 + + + 2 + 5 + 2 + 0 + 0 + 0 + startup_stm32wl55xx_cm4.s + startup_stm32wl55xx_cm4.s + 0 + 0 + + + + + Application/BFU/App + 0 + 0 + 0 + 0 + + 3 + 6 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_boot.c + sfu_boot.c + 0 + 0 + + + 3 + 7 + 1 + 0 + 0 + 0 + ..\BFU\App\sfu_com_loader.c + sfu_com_loader.c + 0 + 0 + + + 3 + 8 + 1 + 0 + 0 + 0 + ..\BFU\App\sfu_com_trace.c + sfu_com_trace.c + 0 + 0 + + + 3 + 9 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_error.c + sfu_error.c + 0 + 0 + + + 3 + 10 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_fwimg_common.c + sfu_fwimg_common.c + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_fwimg_no_swap.c + sfu_fwimg_no_swap.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_fwimg_swap.c + sfu_fwimg_swap.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_interface_crypto_scheme.c + sfu_interface_crypto_scheme.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_kms.c + sfu_kms.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\BFU\App\sfu_loader.c + sfu_loader.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\BFU\App\sfu_new_image.c + sfu_new_image.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ../BFU/App/sfu_test.c + sfu_test.c + 0 + 0 + + + + + Application/BFU/Target + 0 + 0 + 0 + 0 + + 4 + 18 + 1 + 0 + 0 + 0 + ..\BFU\Target\sfu_low_level.c + sfu_low_level.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + ..\BFU\Target\sfu_low_level_flash.c + sfu_low_level_flash.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + ..\BFU\Target\sfu_low_level_flash_ext.c + sfu_low_level_flash_ext.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + ..\BFU\Target\sfu_low_level_flash_int.c + sfu_low_level_flash_int.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + ../BFU/Target/sfu_low_level_security.c + sfu_low_level_security.c + 0 + 0 + + + + + Doc + 1 + 0 + 0 + 0 + + 5 + 23 + 5 + 0 + 0 + 0 + ../readme.txt + readme.txt + 0 + 0 + + + + + Drivers/BSP/STM32WLxx_Nucleo + 0 + 0 + 0 + 0 + + 6 + 24 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + stm32wlxx_nucleo.c + 0 + 0 + + + + + Drivers/STM32WLxx_HAL_Driver + 0 + 0 + 0 + 0 + + 7 + 25 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + stm32wlxx_hal.c + 0 + 0 + + + 7 + 26 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + stm32wlxx_hal_cortex.c + 0 + 0 + + + 7 + 27 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + stm32wlxx_hal_crc.c + 0 + 0 + + + 7 + 28 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + stm32wlxx_hal_crc_ex.c + 0 + 0 + + + 7 + 29 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + stm32wlxx_hal_dma.c + 0 + 0 + + + 7 + 30 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + stm32wlxx_hal_flash.c + 0 + 0 + + + 7 + 31 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + stm32wlxx_hal_flash_ex.c + 0 + 0 + + + 7 + 32 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + stm32wlxx_hal_gpio.c + 0 + 0 + + + 7 + 33 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + stm32wlxx_hal_iwdg.c + 0 + 0 + + + 7 + 34 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + stm32wlxx_hal_pwr.c + 0 + 0 + + + 7 + 35 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + stm32wlxx_hal_pwr_ex.c + 0 + 0 + + + 7 + 36 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + stm32wlxx_hal_rcc.c + 0 + 0 + + + 7 + 37 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + stm32wlxx_hal_rcc_ex.c + 0 + 0 + + + 7 + 38 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + stm32wlxx_hal_rtc.c + 0 + 0 + + + 7 + 39 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + stm32wlxx_hal_rtc_ex.c + 0 + 0 + + + 7 + 40 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi.c + stm32wlxx_hal_spi.c + 0 + 0 + + + 7 + 41 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi_ex.c + stm32wlxx_hal_spi_ex.c + 0 + 0 + + + 7 + 42 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim.c + stm32wlxx_hal_tim.c + 0 + 0 + + + 7 + 43 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim_ex.c + stm32wlxx_hal_tim_ex.c + 0 + 0 + + + 7 + 44 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + stm32wlxx_hal_uart.c + 0 + 0 + + + 7 + 45 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + stm32wlxx_hal_uart_ex.c + 0 + 0 + + + 7 + 46 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + stm32wlxx_hal_exti.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 8 + 47 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Source/Templates/system_stm32wlxx.c + system_stm32wlxx.c + 0 + 0 + + + + + Middlewares/STM32_Secure_Engine + 0 + 0 + 0 + 0 + + 9 + 48 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_application.c + se_interface_application.c + 0 + 0 + + + 9 + 49 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_bootloader.c + se_interface_bootloader.c + 0 + 0 + + + 9 + 50 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_common.c + se_interface_common.c + 0 + 0 + + + + + Middlewares/STM32_Key_Management_Services + 0 + 0 + 0 + 0 + + 10 + 51 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS/se_interface_kms.c + se_interface_kms.c + 0 + 0 + + + + + Drivers/STM32WLxx_LL_Driver + 0 + 0 + 0 + 0 + + 11 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_ll_utils.c + stm32wlxx_ll_utils.c + 0 + 0 + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..08fb83f2 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/Project.uvprojx @@ -0,0 +1,708 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_BFU + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + BFU + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf #L --bincombined --output=$L@L.bin + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + -Wno-format + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED + + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../Core/Inc;../BFU/App;../BFU/Target;../../1_Image_SECoreBin/Inc;../../Linker_Common/MDK-ARM;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../../../../../Middlewares/ST/STM32_Secure_Engine/Interface;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS;../../../../../../Drivers/BSP/STM32WLxx_Nucleo + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + BFU.sct + + + --symdefs=se_interface_appli.txt +--keep=SE_CORE_Bin.o(SE_CORE_Bin) + + + + + + + + Application/Core + + + main.c + 1 + ../Core/Src/main.c + + + stm32wlxx_hal_msp.c + 1 + ../Core/Src/stm32wlxx_hal_msp.c + + + stm32wlxx_it.c + 1 + ../Core/Src/stm32wlxx_it.c + + + + + Application/MDK-ARM + + + se_core_bin.s + 2 + se_core_bin.s + + + startup_stm32wl55xx_cm4.s + 2 + startup_stm32wl55xx_cm4.s + + + + + Application/BFU/App + + + sfu_boot.c + 1 + ../BFU/App/sfu_boot.c + + + sfu_com_loader.c + 1 + ..\BFU\App\sfu_com_loader.c + + + sfu_com_trace.c + 1 + ..\BFU\App\sfu_com_trace.c + + + sfu_error.c + 1 + ../BFU/App/sfu_error.c + + + sfu_fwimg_common.c + 1 + ../BFU/App/sfu_fwimg_common.c + + + sfu_fwimg_no_swap.c + 1 + ../BFU/App/sfu_fwimg_no_swap.c + + + sfu_fwimg_swap.c + 1 + ../BFU/App/sfu_fwimg_swap.c + + + sfu_interface_crypto_scheme.c + 1 + ../BFU/App/sfu_interface_crypto_scheme.c + + + sfu_kms.c + 1 + ../BFU/App/sfu_kms.c + + + sfu_loader.c + 1 + ..\BFU\App\sfu_loader.c + + + sfu_new_image.c + 1 + ..\BFU\App\sfu_new_image.c + + + sfu_test.c + 1 + ../BFU/App/sfu_test.c + + + + + Application/BFU/Target + + + sfu_low_level.c + 1 + ..\BFU\Target\sfu_low_level.c + + + sfu_low_level_flash.c + 1 + ..\BFU\Target\sfu_low_level_flash.c + + + sfu_low_level_flash_ext.c + 1 + ..\BFU\Target\sfu_low_level_flash_ext.c + + + sfu_low_level_flash_int.c + 1 + ..\BFU\Target\sfu_low_level_flash_int.c + + + sfu_low_level_security.c + 1 + ../BFU/Target/sfu_low_level_security.c + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Drivers/BSP/STM32WLxx_Nucleo + + + stm32wlxx_nucleo.c + 1 + ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + + + Drivers/STM32WLxx_HAL_Driver + + + stm32wlxx_hal.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + stm32wlxx_hal_cortex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + stm32wlxx_hal_crc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + stm32wlxx_hal_crc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + stm32wlxx_hal_dma.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + + + stm32wlxx_hal_flash.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + stm32wlxx_hal_flash_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + stm32wlxx_hal_gpio.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + stm32wlxx_hal_iwdg.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + stm32wlxx_hal_pwr.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + stm32wlxx_hal_pwr_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + stm32wlxx_hal_rcc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + stm32wlxx_hal_rcc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + stm32wlxx_hal_rtc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + stm32wlxx_hal_rtc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + stm32wlxx_hal_spi.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi.c + + + stm32wlxx_hal_spi_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi_ex.c + + + stm32wlxx_hal_tim.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim.c + + + stm32wlxx_hal_tim_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim_ex.c + + + stm32wlxx_hal_uart.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + stm32wlxx_hal_uart_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + stm32wlxx_hal_exti.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + + + Drivers/CMSIS + + + system_stm32wlxx.c + 1 + ../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Source/Templates/system_stm32wlxx.c + + + + + Middlewares/STM32_Secure_Engine + + + se_interface_application.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_application.c + + + se_interface_bootloader.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_bootloader.c + + + se_interface_common.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_interface_common.c + + + + + Middlewares/STM32_Key_Management_Services + + + se_interface_kms.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS/se_interface_kms.c + + + + + Drivers/STM32WLxx_LL_Driver + + + stm32wlxx_ll_utils.c + 1 + ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_ll_utils.c + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/STM32WL55JC_Nucleo/Exe/se_interface_appli.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/STM32WL55JC_Nucleo/Exe/se_interface_appli.txt new file mode 100644 index 00000000..6a8982e0 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/STM32WL55JC_Nucleo/Exe/se_interface_appli.txt @@ -0,0 +1,38 @@ +## ARM Linker, 6120001: Last Updated: Fri Sep 25 17:55:14 2020 +0x08007d01 T SE_APP_GetActiveFwInfo +0x08008445 T SE_KMS_Initialize +0x08008171 T SE_KMS_Finalize +0x08008309 T SE_KMS_GetInfo +0x08008305 T SE_KMS_GetFunctionList +0x080083a5 T SE_KMS_GetSlotList +0x08008371 T SE_KMS_GetSlotInfo +0x080083dd T SE_KMS_GetTokenInfo +0x08008339 T SE_KMS_GetMechanismInfo +0x080084d9 T SE_KMS_OpenSession +0x08007dfd T SE_KMS_CloseSession +0x08007e29 T SE_KMS_CreateObject +0x08007f81 T SE_KMS_DestroyObject +0x080082c9 T SE_KMS_GetAttributeValue +0x08008515 T SE_KMS_SetAttributeValue +0x0800820d T SE_KMS_FindObjectsInit +0x080081a1 T SE_KMS_FindObjects +0x080081dd T SE_KMS_FindObjectsFinal +0x080080fd T SE_KMS_EncryptInit +0x08008089 T SE_KMS_Encrypt +0x08008135 T SE_KMS_EncryptUpdate +0x080080c5 T SE_KMS_EncryptFinal +0x08007ed1 T SE_KMS_DecryptInit +0x08007e61 T SE_KMS_Decrypt +0x08007f05 T SE_KMS_DecryptUpdate +0x08007e9d T SE_KMS_DecryptFinal +0x08008021 T SE_KMS_DigestInit +0x08007fb1 T SE_KMS_Digest +0x08008051 T SE_KMS_DigestUpdate +0x08007fed T SE_KMS_DigestFinal +0x08008591 T SE_KMS_SignInit +0x08008551 T SE_KMS_Sign +0x08008609 T SE_KMS_VerifyInit +0x080085c9 T SE_KMS_Verify +0x08007f41 T SE_KMS_DeriveKey +0x08008245 T SE_KMS_GenerateKeyPair +0x08008291 T SE_KMS_GenerateRandom diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/se_core_bin.s b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/se_core_bin.s new file mode 100644 index 00000000..0d96feed --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/se_core_bin.s @@ -0,0 +1,20 @@ +;/****************************************************************************** +;* File Name : se_core_bin.s +;* Author : MCD Application Team +;* Description : Include SECoreBin binary. +;******************************************************************************** +;* @attention +;* +;* Copyright (c) 2017 STMicroelectronics. All rights reserved. +;* +;* This software component is licensed by ST under Ultimate Liberty license +;* SLA0044, the "License"; You may not use this file except in compliance with +;* the License. You may obtain a copy of the License at: +;* www.st.com/SLA0044 +;* +;****************************************************************************** +; +; + AREA SE_CORE_Bin, CODE, READONLY + INCBIN .\..\..\1_Image_SECoreBin\MDK-ARM\STM32WL55JC_Nucleo\Exe\SECoreBin.bin + END diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/startup_stm32wl55xx_cm4.s new file mode 100644 index 00000000..7b638c87 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/MDK-ARM/startup_stm32wl55xx_cm4.s @@ -0,0 +1,365 @@ +;****************************************************************************** +;* File Name : startup_stm32wl55xx_cm4.s +;* Author : MCD Application Team +;* Description : STM32WL55xx devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the CortexM4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;****************************************************************************** +;* @attention +;* +;* Copyright (c) 2020 STMicroelectronics. All rights reserved. +;* +;* This software component is licensed by ST under 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: +;* opensource.org/licenses/Apache-2.0 +;* +;****************************************************************************** + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x1A00 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x0 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD and PVM detector + DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSR Underflow Interrupts + DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt + DCD FLASH_IRQHandler ; FLASH global Interrupt + DCD RCC_IRQHandler ; RCC Interrupt + DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt + DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt + DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt + DCD EXTI3_IRQHandler ; EXTI Line 3 Interrup + DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt + DCD ADC_IRQHandler ; ADC Interrupt + DCD DAC_IRQHandler ; DAC Interrupt + DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV and PWR CPU M0+ HOLD wakeup Interrupt + DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts + DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt + DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupts + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt + DCD TIM2_IRQHandler ; TIM2 Global Interrupt + DCD TIM16_IRQHandler ; TIM16 Global Interrupt + DCD TIM17_IRQHandler ; TIM17 Global Interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt + DCD SPI1_IRQHandler ; SPI1 Interrupt + DCD SPI2_IRQHandler ; SPI2 Interrupt + DCD USART1_IRQHandler ; USART1 Interrupt + DCD USART2_IRQHandler ; USART2 Interrupt + DCD LPUART1_IRQHandler ; LPUART1 Interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 Interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 Interrupt + DCD EXTI15_10_IRQHandler ; EXTI Lines1[15:10 ]Interrupts + DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 Interrupt + DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt + DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt + DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt + DCD HSEM_IRQHandler ; HSEM0 Interrupt + DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt + DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt + DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt + DCD AES_IRQHandler ; AES Interrupt + DCD RNG_IRQHandler ; RNG1 Interrupt + DCD PKA_IRQHandler ; PKA Interrupt + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt + DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_PVM_IRQHandler [WEAK] + EXPORT TAMP_STAMP_LSECSS_SSRU_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT DAC_IRQHandler [WEAK] + EXPORT C2SEV_PWR_C2H_IRQHandler [WEAK] + EXPORT COMP_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT LPTIM3_IRQHandler [WEAK] + EXPORT SUBGHZSPI_IRQHandler [WEAK] + EXPORT IPCC_C1_RX_IRQHandler [WEAK] + EXPORT IPCC_C1_TX_IRQHandler [WEAK] + EXPORT HSEM_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SUBGHZ_Radio_IRQHandler [WEAK] + EXPORT AES_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT PKA_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_IRQHandler [WEAK] + EXPORT DMA2_Channel5_IRQHandler [WEAK] + EXPORT DMA2_Channel6_IRQHandler [WEAK] + EXPORT DMA2_Channel7_IRQHandler [WEAK] + EXPORT DMAMUX1_OVR_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_PVM_IRQHandler +TAMP_STAMP_LSECSS_SSRU_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC_IRQHandler +DAC_IRQHandler +C2SEV_PWR_C2H_IRQHandler +COMP_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +LPUART1_IRQHandler +LPTIM1_IRQHandler +LPTIM2_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +LPTIM3_IRQHandler +SUBGHZSPI_IRQHandler +IPCC_C1_RX_IRQHandler +IPCC_C1_TX_IRQHandler +HSEM_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SUBGHZ_Radio_IRQHandler +AES_IRQHandler +RNG_IRQHandler +PKA_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_IRQHandler +DMA2_Channel5_IRQHandler +DMA2_Channel6_IRQHandler +DMA2_Channel7_IRQHandler +DMAMUX1_OVR_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/.cproject new file mode 100644 index 00000000..635041a5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/.cproject @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/.project new file mode 100644 index 00000000..e1053b57 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/.project @@ -0,0 +1,281 @@ + + + 1_Image_BFU + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doc/readme.txt + 1 + $%7BPARENT-1-PROJECT_LOC%7D/readme.txt + + + Application/Core/main.c + 1 + PARENT-1-PROJECT_LOC/Core/Src/main.c + + + Application/Core/stm32wlxx_hal_msp.c + 1 + PARENT-1-PROJECT_LOC/Core/Src/stm32wlxx_hal_msp.c + + + Application/Core/stm32wlxx_it.c + 1 + PARENT-1-PROJECT_LOC/Core/Src/stm32wlxx_it.c + + + Drivers/CMSIS/system_stm32wlxx.c + 1 + PARENT-6-PROJECT_LOC/Drivers/CMSIS/Device/ST/STM32WLxx/Source/Templates/system_stm32wlxx.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cortex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_exti.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gpio.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_iwdg.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_spi.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_spi_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_spi_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_tim.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_tim_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_tim_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + Drivers/STM32WLxx_LL_Driver/stm32wlxx_ll_utils.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_ll_utils.c + + + Middlewares/STM32_Key_Management_Services/se_interface_kms.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Key_Management_Services/iKMS/se_interface_kms.c + + + Middlewares/STM32_Secure_Engine/se_interface_application.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_application.c + + + Middlewares/STM32_Secure_Engine/se_interface_bootloader.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_bootloader.c + + + Middlewares/STM32_Secure_Engine/se_interface_common.c + 1 + PARENT-6-PROJECT_LOC/Middlewares/ST/STM32_Secure_Engine/Core/se_interface_common.c + + + Application/BFU/App/sfu_boot.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_boot.c + + + Application/BFU/App/sfu_com_loader.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_com_loader.c + + + Application/BFU/App/sfu_com_trace.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_com_trace.c + + + Application/BFU/App/sfu_error.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_error.c + + + Application/BFU/App/sfu_fwimg_common.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_fwimg_common.c + + + Application/BFU/App/sfu_fwimg_swap.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_fwimg_swap.c + + + Application/BFU/App/sfu_fwimg_no_swap.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_fwimg_no_swap.c + + + Application/BFU/App/sfu_interface_crypto_scheme.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_interface_crypto_scheme.c + + + Application/BFU/App/sfu_kms.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_kms.c + + + Application/BFU/App/sfu_loader.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_loader.c + + + Application/BFU/App/sfu_new_image.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_new_image.c + + + Application/BFU/App/sfu_test.c + 1 + PARENT-1-PROJECT_LOC/BFU/App/sfu_test.c + + + Application/BFU/Target/sfu_low_level.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level.c + + + Application/BFU/Target/sfu_low_level_flash.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash.c + + + Application/BFU/Target/sfu_low_level_flash_ext.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash_ext.c + + + Application/BFU/Target/sfu_low_level_flash_int.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_flash_int.c + + + Application/BFU/Target/sfu_low_level_security.c + 1 + PARENT-1-PROJECT_LOC/BFU/Target/sfu_low_level_security.c + + + Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + 1 + PARENT-6-PROJECT_LOC/Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Core/sfu_secorebin_inc.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Core/sfu_secorebin_inc.c new file mode 100644 index 00000000..3c5470dc --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Core/sfu_secorebin_inc.c @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * @file sfu_secorebin_inc.c + * @author MCD Application Team + * @brief Include SECoreBin binary. + ****************************************************************************** + * @attention + * + *

      © Copyright(c) 2017 STMicroelectronics International N.V. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "string.h" + +#if defined (__GNUC__) +asm(".section SE_CORE_Bin,\"a\";" + ".incbin \"../../1_Image_SECoreBin/STM32CubeIDE/Debug/SECoreBin.bin\";" +); +#endif + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_AT_Slave/STM32CubeIDE/Application/Core/syscalls.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Core/syscalls.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_AT_Slave/STM32CubeIDE/Application/Core/syscalls.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Core/syscalls.c diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM0PLUS/Application/Core/sysmem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Core/sysmem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM0PLUS/Application/Core/sysmem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Core/sysmem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM4/Application/Startup/startup_stm32wl55jcix.s b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM4/Application/Startup/startup_stm32wl55jcix.s rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/BFU.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/BFU.ld new file mode 100644 index 00000000..f6726648 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/BFU.ld @@ -0,0 +1,162 @@ +/* +** LinkerScript +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = SB_region_RAM_end + 1; /* end of SB_SRAM1 * + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0; /* required amount of heap */ +_Min_Stack_Size = 0x2000; /* specific stack provided inside secured area */ + +INCLUDE mapping_fwimg.ld +INCLUDE mapping_sbsfu.ld + +/* Define output sections */ +SECTIONS +{ + .isr_vector : + { + . = ALIGN(8); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(8); + } >INTVECT_ROM_region + + SE_CORE_Bin : + { + KEEP(*(SE_CORE_Bin)); + } > SE_ROM_region + + .SE_IF_Code : { KEEP(*se_interface_application.o (.text .text*)) + KEEP(*se_interface_bootloader.o (.text .text*)) + KEEP(*se_interface_common.o (.text .text*)) + KEEP(*se_interface_kms.o (.text .text*)) + } >SE_IF_ROM_region + + .text : + { + . = ALIGN(8); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(8); + _etext = .; /* define a global symbols at end of code */ + } >SB_ROM_region + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >SB_ROM_region + + .ARM.extab : + { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >SB_ROM_region + + .ARM : + { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >SB_ROM_region + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >SB_ROM_region + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >SB_ROM_region + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >SB_ROM_region + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + } >SB_RAM_region AT>SB_ROM_region + + + /* Uninitialized data section */ + . = ALIGN(8); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >SB_RAM_region + + /* User_heap_stack section, used to check that there is enough "SRAM1" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SB_RAM_region + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/se_interface.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/se_interface.txt new file mode 100644 index 00000000..05aa5e0b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/STM32CubeIDE/se_interface.txt @@ -0,0 +1,40 @@ +SE_APP_GetActiveFwInfo +SE_APP_SVC_Handler +SE_SYS_SaveDisableIrq +SE_SYS_RestoreEnableIrq +SE_KMS_Initialize +SE_KMS_Finalize +SE_KMS_GetInfo +SE_KMS_GetFunctionList +SE_KMS_GetSlotList +SE_KMS_GetSlotInfo +SE_KMS_GetTokenInfo +SE_KMS_GetMechanismInfo +SE_KMS_OpenSession +SE_KMS_CloseSession +SE_KMS_CreateObject +SE_KMS_DestroyObject +SE_KMS_GetAttributeValue +SE_KMS_SetAttributeValue +SE_KMS_FindObjectsInit +SE_KMS_FindObjects +SE_KMS_FindObjectsFinal +SE_KMS_EncryptInit +SE_KMS_Encrypt +SE_KMS_EncryptUpdate +SE_KMS_EncryptFinal +SE_KMS_DecryptInit +SE_KMS_Decrypt +SE_KMS_DecryptUpdate +SE_KMS_DecryptFinal +SE_KMS_DigestInit +SE_KMS_Digest +SE_KMS_DigestUpdate +SE_KMS_DigestFinal +SE_KMS_SignInit +SE_KMS_Sign +SE_KMS_VerifyInit +SE_KMS_Verify +SE_KMS_DeriveKey +SE_KMS_GenerateKeyPair +SE_KMS_GenerateRandom diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/readme.txt new file mode 100644 index 00000000..82e264f5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_BFU/readme.txt @@ -0,0 +1,166 @@ +/** + @page 1_Image_BFU / Boot and Firmware Update Demo Application + + @verbatim + ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* + * @file readme.txt + * @brief This application shows Boot and Firmware Update example. + ****************************************************************************** + * + * Copyright (c) 2017 STMicroelectronics. All rights reserved. + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + @endverbatim + +@par Application Description + +The Boot (B) and Firmware Update (FU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates. +In addition, Secure Boot (Root of Trust services) checks and activates the STM32 security mechanisms (if any), and checks the +authenticity and integrity of user application code before every execution to ensure that invalid or malicious code +cannot be run. The Firmware Update application receives the encrypted firmware image, decrypts it, then checks +the authenticity and integrity of the code before installing it. + +The key management services provide cryptographic services to the user application through the pkcs11 APIs +(KEY ID based APIs). User application keys are stored and can be updated in a secure way (authenticity check, data decryption and +data integrity check). +This example handles 2 firmware images located in 1 active slot and 1 download area in FLASH allowing to demonstrate +features like: + - download a new firmware image from the application + - resume firmware update procedure in case of power off during installation + - rollback on the previous firmware if the new active image is not validated (selft-tests KO) at first start-up. + +For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" available from the +STMicroelectronics microcontroller website www.st.com. + +@par Keywords + +Security, SBSFU, MPU + +@par Directory contents + + - 1_Image_BFU/Core/Src/main.c Main application file + - 1_Image_BFU/Core/Src/stm32wlxx_hal_msp.c HAL MSP module + - 1_Image_BFU/Core/Src/stm32wlxx_it.c STM32 interrupt handlers + - 1_Image_BFU/Core/Inc/app_hw.h Hardware definitions for application + - 1_Image_BFU/Core/Inc/main.h Header file for main.c + - 1_Image_BFU/Core/Inc/stm32wlxx_hal_conf.h HAL configuration file + - 1_Image_BFU/Core/Inc/stm32wlxx_it.h Header file for stm32wlxx_it.c + - 1_Image_BFU/Core/Inc/stm32wlxx_nucleo_conf.h BSP configuration file + - 1_Image_BFU/BFU/App/sfu_boot.c Secure Boot (SB): entry/exit points and state machine + - 1_Image_BFU/BFU/App/sfu_com_loader.c BFU communication module: local loader part + - 1_Image_BFU/BFU/App/sfu_com_trace.c BFU communication module: trace part + - 1_Image_BFU/BFU/App/sfu_error.c BFU errors management + - 1_Image_BFU/BFU/App/sfu_fwimg_common.c BFU image handling: common functionalities/services + - 1_Image_BFU/BFU/App/sfu_fwimg_swap.c BFU image handling: FW upgrade without swap area services + - 1_Image_BFU/BFU/App/sfu_fwimg_no_swap.c BFU image handling: FW upgrade with swap area services + - 1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.c Crypto scheme implementation based on KMS API + - 1_Image_BFU/BFU/App/sfu_kms.c Key management service blob importation handling + - 1_Image_BFU/BFU/App/sfu_loader.c BFU Local Loader + - 1_Image_BFU/BFU/App/sfu_new_image.c BFU image handling: manage the new firmware image storage and installation + - 1_Image_BFU/BFU/App/sfu_test.c BFU security protection automatic test + - 1_Image_BFU/BFU/App/app_sfu.h Software configuration of BFU application + - 1_Image_BFU/BFU/App/sfu_boot.h Header file for sfu_boot.c + - 1_Image_BFU/BFU/App/sfu_com_loader.h Header file for sfu_com_loader.c + - 1_Image_BFU/BFU/App/sfu_com_trace.h Header file for sfu_com_trace.c + - 1_Image_BFU/BFU/App/sfu_def.h General definition for BFU application + - 1_Image_BFU/BFU/App/sfu_error.h Header file for sfu_error.c file + - 1_Image_BFU/BFU/App/sfu_fsm_states.h BFU FSM states definitions + - 1_Image_BFU/BFU/App/sfu_fwimg_internal.h Internal definitions for firmware image handling (sfu_fwimg_core.c and sfu_fwimg_services.c) + - 1_Image_BFU/BFU/App/sfu_fwimg_regions.h FLASH regions definitions for image handling + - 1_Image_BFU/BFU/App/sfu_fwimg_services.h Header file for sfu_fwimg_services.c + - 1_Image_BFU/BFU/App/sfu_interface_crypto_scheme.h Header file for sfu_interface_crypto_scheme.h + - 1_Image_BFU/BFU/App/sfu_kms.h Header file for sfu_kms.c + - 1_Image_BFU/BFU/App/sfu_loader.h Header file for sfu_loader.c + - 1_Image_BFU/BFU/App/sfu_new_image.h Header file for sfu_new_image.c + - 1_Image_BFU/BFU/App/sfu_test.h Header file for sfu_test.c + - 1_Image_BFU/BFU/App/sfu_trace.h Header file for sfu_trace.c + - 1_Image_BFU/BFU/Target/sfu_low_level.c BFU general low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash.c BFU flash low level interface (wrapper) + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_int.c BFU internal flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.c BFU external flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_security.c BFU security low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level.h Header file for general low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash.h Header file for flash low level interface (wrapper) + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_int.h Header file for internal flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_flash_ext.h Header file for external flash low level interface + - 1_Image_BFU/BFU/Target/sfu_low_level_security.h Header file for security low level interface + +@par Hardware and Software environment + + - This example runs on STM32WL55xx devices. + - This example has been tested with NUCLEO-WL55JC RevC board and can be easily tailored to any other supported device and + development board. + - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware is a feature provided by + STM32Cube programmer available on www.st.com. + - This example is linked with SE_Core binary generated by Secure Engine Core binary generation project. + - This example needs a terminal emulator. + - By default, SBSFU is configured in development mode. To switch in production mode, refer to AN5056 "Integration + guide - software expansion for STM32Cube" available from the STMicroelectronics microcontroller website + www.st.com. + - Microsoft Windows has a limitation whereby paths to files and directories cannot be longer than 256 characters. + Paths to files exceeding that limits cause tools (e.g. compilers, shell scripts) to fail reading from or writing + to such files. + As a workaround, it is advised to use the subst.exe command from within a command prompt to set up a local drive + out of an existing directory on the hard drive, such as: + C:\> subst X: \Firmware + +@par How to use it ? + +Several steps to run BFU application : + +1. Compile projects in the following order. This is mandatory as each project requests some objects generated by the + compilation of the previous one: + - 1_Image_SECoreBin (see also SECoreBin/readme.txt) + - 1_Image_BFU + - 1_Image_UserApp (see also UserApp/readme.txt) + +2. Before loading BFU image into the target, please ensure with STM32CubeProgrammer available on www.st.com that the + following are valid for the device: + - RDP Level 0 + - Write Protection disabled on all FLASH pages + - Chip has been erased + +3. Use a terminal emulator (Tera Term for example, open source free software terminal emulator that can be downloaded + from https://osdn.net/projects/ttssh2/) for UART connection with the board. + Support of YMODEM protocol is required. Serial port configuration should be : + - Baud rate = 115200 + - Data = 8 bits + - Parity = none + - Stop = 1 bit + - Flow control = none + +4. Load BFU image into target memory with your preferred toolchain or STM32CubeProgammer. + +5. Once the BFU software is downloaded, power cycle the board (unplug/plug USB cable) : the BFU + application starts and configures the security mechanisms if some of them are enabled. + +6. [If RDP is enabled] Power cycle the board a second time (unplug/plug the USB cable): the BFU application starts with + the configured securities turned on and the Tera Term connection is possible. + Caution: Make sure to use an up-to-date version of ST-LINK firmware else BFU may not start. + +7. At startup (Power On or Reset button pushed) welcome information are displayed on terminal emulator. + Green LED blinks every 3 seconds when a local download is waited. + Green LED blinks every 250 ms in case of error in option bytes configuration. + +8. Send the user encrypted firmware file (\2_Slots\1_Image_UserApp\Binary\UserApp.sfb) with Tera Term by using menu + "File > Transfer > YMODEM > Send..." + +Note1 : Press User push-button (B1) at reset to force a local download if an application is already installed. +Note2 : The following steps enable the protections disabled by default: + - Comment "SECBOOT_DISABLE_SECURITY_IPS" in app_sfu.h. This will enable RDP, WRP, DAP, DMA, IWDG protections + as well as attack surface reduction with MPU. + - As TAMPER detection can be very sensitive, the protection remains disabled by default. + Uncomment "SFU_TAMPER_PROTECT_ENABLE" in app_sfu.h to enable it. + These features achieve an attack surface reduction but will not make it possible to protect secrets. +Note3 : for Linux users Minicom can be used but to do so you need to compile the BFU project with the MINICOM_YMODEM + switch enabled (app_sfu.h) + + *

      © COPYRIGHT STMicroelectronics

      + */ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/Binary/ECCKEY.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Binary/ECCKEY.txt similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/Binary/ECCKEY.txt rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Binary/ECCKEY.txt diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_KMS_Blob/Binary/iv.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Binary/iv.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_KMS_Blob/Binary/iv.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Binary/iv.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.ewd new file mode 100644 index 00000000..62ef1fde --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.ewd @@ -0,0 +1,1419 @@ + + + 3 + + STM32WL55JC_Nucleo_1_Image_KMS_Blob + + ARM + + 1 + + C-SPY + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.ewp new file mode 100644 index 00000000..e381814c --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.ewp @@ -0,0 +1,1054 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_KMS_Blob + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + cmd /C "cmd /C $PROJ_DIR$\postbuild.bat "$PROJ_DIR$" "KMS_Blob" 1 " + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + User + + $PROJ_DIR$\..\Src\kms_blob_example_keys.c + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/EWARM/postbuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/postbuild.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/EWARM/postbuild.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/postbuild.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/EWARM/stm32wl55xx_flash_cm0plus.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/stm32wl55xx_flash_cm4.icf similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/EWARM/stm32wl55xx_flash_cm0plus.icf rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/EWARM/stm32wl55xx_flash_cm4.icf diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/MDK-ARM/KMS_Blob.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/KMS_Blob.sct similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/MDK-ARM/KMS_Blob.sct rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/KMS_Blob.sct diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/KMS_blob.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/KMS_blob.bin new file mode 100644 index 00000000..bd13cab7 Binary files /dev/null and b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/KMS_blob.bin differ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/Project.uvoptx new file mode 100644 index 00000000..4a478254 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/Project.uvoptx @@ -0,0 +1,220 @@ + + + + 1.0 + +
      ### uVision Project, (C) Keil Software
      + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32WL55JC_Nucleo_1_Image_KMS_Blob + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 1 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + + + + + + + + + + + BIN\UL2CM3.DLL + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Doc + 1 + 0 + 0 + 0 + + 1 + 1 + 5 + 0 + 0 + 0 + ../readme.txt + readme.txt + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ../Src/kms_blob_example_keys.c + kms_blob_example_keys.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..f5c7e0c9 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/Project.uvprojx @@ -0,0 +1,422 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_KMS_Blob + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + KMS_blob + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 1 + fromelf #L --bin --output=$L../../@L.bin + postbuild.bat . @L 1 + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4 + + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../1_Image_SECoreBin/Inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 0 + 0 + + + + KMS_Blob.sct + + + --diag_suppress L6305W + + + + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Application/User + + + kms_blob_example_keys.c + 1 + ../Src/kms_blob_example_keys.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/MDK-ARM/postbuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/postbuild.bat similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/MDK-ARM/postbuild.bat rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/MDK-ARM/postbuild.bat diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/.cproject new file mode 100644 index 00000000..447ffaf6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/.cproject @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/.project new file mode 100644 index 00000000..ae535727 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/.project @@ -0,0 +1,46 @@ + + + 1_Image_KMS_Blob + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doc/readme.txt + 1 + $%7BPARENT-1-PROJECT_LOC%7D/readme.txt + + + Application/User/kms_blob_example_keys.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/kms_blob_example_keys.c + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_KMS_Blob/STM32CubeIDE/KMS_Blob.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/KMS_Blob.ld similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_KMS_Blob/STM32CubeIDE/KMS_Blob.ld rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/STM32CubeIDE/KMS_Blob.ld diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/Src/kms_blob_example_keys.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Src/kms_blob_example_keys.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_KMS_Blob/Src/kms_blob_example_keys.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/Src/kms_blob_example_keys.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/readme.txt new file mode 100644 index 00000000..d7ddf143 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_KMS_Blob/readme.txt @@ -0,0 +1,62 @@ +/** + @page 1_Image_KMS_Blob / Key Management Services / Blob generation project. + + @verbatim + ******************** (C) COPYRIGHT 2019 STMicroelectronics ******************* + * @file readme.txt + * @brief Key Management Services Blob generation. + * Allows to generate Blob to be injected to a device supporting + * KMS ImportBlob(). + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + @endverbatim + +@par Application Description + +This application is used to generate Key Management Services Blob binary file to be downloaded +with KMS through the ImportBlob() API. + +You can edit your own keys to generate your own Blob. + +For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" +available from the STMicroelectronics microcontroller website www.st.com. + +@par Keywords + +Cryptography, KMS, Provisioning + +@par Directory contents + + - 1_Image_KMS_Blob/Src/kms_blob_example_keys.c KMS blob objects definition + - 1_Image_KMS_Blob/Binary/ECCKEY.txt Private ECCDSA key for signature verification + - 1_Image_KMS_Blob/Binary/iv.bin Encryption/decryption initialization vector + - 1_Image_KMS_Blob/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin Public key for AES CBC encryption + +@par Hardware and Software environment + + - This example runs on STM32WL55xx devices + - This example has been tested with NUCLEO-WL55JC RevC board and can be + easily tailored to any other supported device and development board. + - Python installation required. In addition, install the appropriate python modules as described in + Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages\readme.txt + + +@par How to use it ? + +In order to generate Secure Key Storage Blob file, you must do the following : + - Edit the .c source file, where examples of keys are provided. Update with your own keys. + - Open your preferred toolchain + - Rebuild the project + + *

      © COPYRIGHT STMicroelectronics

      + */ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/ECCKEY1.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/ECCKEY1.txt similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/ECCKEY1.txt rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/ECCKEY1.txt diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/nonce.bin b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/nonce.bin similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Binary/nonce.bin rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Binary/nonce.bin diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.ewd new file mode 100644 index 00000000..02776c9f --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.ewd @@ -0,0 +1,1419 @@ + + + 3 + + STM32WL55JC_Nucleo_1_Image_SECoreBin + + ARM + + 1 + + C-SPY + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.ewp new file mode 100644 index 00000000..37823294 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.ewp @@ -0,0 +1,1181 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_SECoreBin + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + cmd /C "cmd /C $PROJ_DIR$\prebuild.bat "$PROJ_DIR$" " + + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + User + + $PROJ_DIR$\..\Src\se_low_level.c + + + $PROJ_DIR$\..\Src\kms_low_level.c + + + $PROJ_DIR$\..\Src\nvms_low_level.c + + + $PROJ_DIR$\..\Src\ca_low_level.c + + + + + Drivers + + STM32WLxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cryp.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cryp_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pka.c + + + + + Middlewares + + STM32_Secure_Engine + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_callgate.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_exception.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_fwimg.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_startup.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_user_application.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Core\se_utils.c + + + + STM32_Key_Management_Services + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_der_x962.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_ecc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_entry.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_init.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_mem.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_objects.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Core\kms_platf_objects.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_digest.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_dyn_obj.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_enc_dec.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_key_mgt.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_nvm_storage.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Modules\kms_sign_verify.c + + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\ST\STM32_Key_Management_Services\Interface\CryptoApi\ca_core.c + + + + Third_Party + + mbed-crypto + + $PROJ_DIR$\..\..\..\..\..\..\Middlewares\Third_Party\mbed-crypto\library\sha256.c + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_KMS_Blob/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_KMS_Blob/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat new file mode 100644 index 00000000..c46620a8 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat @@ -0,0 +1,155 @@ +::Post build for SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files (x86)\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfu=%userAppBinary%\\%execname%.sfu" +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" +set "partialbin=%userAppBinary%\\Partial%execname%.bin" +set "partialsfb=%userAppBinary%\\Partial%execname%.sfb" +set "partialsfu=%userAppBinary%\\Partial%execname%.sfu" +set "partialsign=%userAppBinary%\\Partial%execname%.sign" +set "partialoffset=%userAppBinary%\\Partial%execname%.offset" +set "ref_userapp=%projectdir%\\RefUserApp.bin" + + +set "nonce=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\nonce.bin" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\Project.out" +set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_GCM.bin" +set "magic=SFU%fwid%" +set "offset=512" +set "alignment=16" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +set "command=%python%%prepareimage% enc -k %oemkey% -n %nonce% %bin% %sfu% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sign -k %oemkey% -n %nonce% %bin% %sign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% %sfb% -o %offset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% -o %offset% %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +::Partial image generation if reference userapp exists +if not exist "%ref_userapp%" ( +goto :bigelf +) +set "command=%python%%prepareimage% diff -1 %ref_userapp% -2 %bin% %partialbin% -a %alignment% --poffset %partialoffset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% enc -k %oemkey% -n %nonce% %partialbin% %partialsfu% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sign -k %oemkey% -n %nonce% %partialbin% %partialsign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% -o %offset% --pfw %partialsfu% --ptag %partialsign% --poffset %partialoffset% %partialsfb%>> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% +if exist "%ref_userapp%" ( +del %partialsign% +del %partialbin% +del %partialsfu% +del %partialoffset% +) + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat new file mode 100644 index 00000000..2276fbc6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat @@ -0,0 +1,145 @@ +::Post build for SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files (x86)\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" +set "partialbin=%userAppBinary%\\Partial%execname%.bin" +set "partialsfb=%userAppBinary%\\Partial%execname%.sfb" +set "partialsign=%userAppBinary%\\Partial%execname%.sign" +set "partialoffset=%userAppBinary%\\Partial%execname%.offset" +set "ref_userapp=%projectdir%\\RefUserApp.bin" + +set "oemkey=" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\Project.out" +set "magic=SFU%fwid%" +set "offset=512" +set "alignment=16" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" > %projectdir%\output.txt 2>&1 +IF %ERRORLEVEL% NEQ 0 goto :error +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +:: no encryption +set "command=%python%%prepareimage% sha256 %bin% %sign% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:: no encryption so pack the binary file +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% %sfb% -o %offset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% -o %offset% %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +::Partial image generation if reference userapp exists +if not exist "%ref_userapp%" ( +goto :bigelf +) +set "command=%python%%prepareimage% diff -1 %ref_userapp% -2 %bin% %partialbin% -a %alignment% --poffset %partialoffset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sha256 %partialbin% %partialsign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% -o %offset% --pfw %partialbin% --ptag %partialsign% --poffset %partialoffset% %partialsfb%>> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% +if exist "%ref_userapp%" ( +del %partialsign% +del %partialbin% +del %partialoffset% +) + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat new file mode 100644 index 00000000..91bbd1d5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat @@ -0,0 +1,154 @@ +::Post build for SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files (x86)\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files (x86)\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfu=%userAppBinary%\\%execname%.sfu" +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" +set "partialbin=%userAppBinary%\\Partial%execname%.bin" +set "partialsfb=%userAppBinary%\\Partial%execname%.sfb" +set "partialsfu=%userAppBinary%\\Partial%execname%.sfu" +set "partialsign=%userAppBinary%\\Partial%execname%.sign" +set "partialoffset=%userAppBinary%\\Partial%execname%.offset" +set "ref_userapp=%projectdir%\\RefUserApp.bin" + +set "iv=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\iv.bin" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\EWARM\\STM32WL55JC_Nucleo\\Exe\\Project.out" +set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_CBC.bin" +set "magic=SFU%fwid%" +set "offset=512" +set "alignment=16" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +set "command=%python%%prepareimage% enc -k %oemkey% -i %iv% %bin% %sfu% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sha256 %bin% %sign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% %sfb% -o %offset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% -o %offset% %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -v 0 -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +::Partial image generation if reference userapp exists +if not exist "%ref_userapp%" ( +goto :bigelf +) +set "command=%python%%prepareimage% diff -1 %ref_userapp% -2 %bin% %partialbin% -a %alignment% --poffset %partialoffset% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% enc -k %oemkey% -i %iv% %partialbin% %partialsfu% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sha256 %partialbin% %partialsign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% -o %offset% --pfw %partialsfu% --ptag %partialsign% --poffset %partialoffset% %partialsfb%>> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% +if exist "%ref_userapp%" ( +del %partialsign% +del %partialbin% +del %partialsfu% +del %partialoffset% +) + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/prebuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/prebuild.bat new file mode 100644 index 00000000..4e8662aa --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/prebuild.bat @@ -0,0 +1,147 @@ +@echo off +echo prebuild.bat : started > %1\\output.txt +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::comment this line to force python +::python is used if windows executable not found +pushd %1\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Prebuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto prebuild +) +:py +::line for python +echo Prebuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +echo "python: %prepareimage%" >> %1\\output.txt 2>>&1 +:prebuild +set "crypto_h=%1\\..\\Inc\\se_crypto_config.h" + +::clean +if exist %1\\crypto.txt ( + del %1\\crypto.txt +) + +if exist %1\\postbuild.bat ( + del %1\\postbuild.bat +) + +::get crypto name +set "command=%python%%prepareimage% conf %crypto_h% > %1\\crypto.txt" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set /P crypto=<%1\\crypto.txt >> %1\\output.txt 2>>&1 +echo crypto %crypto% selected >> %1\\output.txt 2>>&1 + +set "cortex=V7M" + +set "KMS_config=%1\kms_platf_objects_config.h" +set "KMS_tmp=%1\kms_platf_objects_config.h.tmp" + +::Patch KMS embedded keys with Blob Keys +set "kmsblob_ecckey=%SBSFUBootLoader%\\1_Image_KMS_Blob\\Binary\\ECCKEY.txt" +set "command=%python%%prepareimage% inject -k %kmsblob_ecckey% -f %1\..\Inc\kms_platf_objects_config.h.pattern -p @ECDSA_BLOB_KEY@ %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "kmsblob_oemkey=%SBSFUBootLoader%\\1_Image_KMS_Blob\\Binary\\OEM_KEY_COMPANY1_key_AES_CBC.bin" +set "command=%python%%prepareimage% inject -k %kmsblob_oemkey% -f %KMS_tmp% -p @AES_BLOB_KEY@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +if "%crypto%"=="SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM" ( + set "type=GCM" + goto AES128 +) +if "%crypto%"=="SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256" ( + set "type=CBC" + goto AES128 +) +::For KMS dummy AES keys are needed (reusing AES_CBC inputs files) +if "%crypto%"=="SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256" ( + set "type=CBC" + goto AES128 +) +goto end + +:AES128 +set "oemkey=%1\\..\\Binary\\OEM_KEY_COMPANY1_key_AES_%type%.bin" +set "command=%python%%prepareimage% inject -k %oemkey% -f %KMS_tmp% -p @AES_SBSFU_KEY_1@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "oemkey=%1\\..\\Binary\\OEM_KEY_COMPANY2_key_AES_%type%.bin" +IF NOT EXIST %oemkey% goto AES128_end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %oemkey% -f %KMS_tmp% -p @AES_SBSFU_KEY_2@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "oemkey=%1\\..\\Binary\\OEM_KEY_COMPANY3_key_AES_%type%.bin" +IF NOT EXIST %oemkey% goto AES128_end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %oemkey% -f %KMS_tmp% -p @AES_SBSFU_KEY_3@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +:AES128_end +::For KMS dummy ECC keys are needed +::if "%crypto%"=="SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM" goto end +goto ECDSA + +:ECDSA +set "ecckey=%1\\..\\Binary\\ECCKEY1.txt" +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %ecckey% -f %KMS_tmp% -p @ECDSA_SBSFU_KEY_1@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "ecckey=%1\\..\\Binary\\ECCKEY2.txt" +IF NOT EXIST %ecckey% goto end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %ecckey% -f %KMS_tmp% -p @ECDSA_SBSFU_KEY_2@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "ecckey=%1\\..\\Binary\\ECCKEY3.txt" +IF NOT EXIST %ecckey% goto end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %ecckey% -f %KMS_tmp% -p @ECDSA_SBSFU_KEY_3@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +goto end + + +:end +del %KMS_tmp% +set "command=copy %1\\%crypto%.bat %1\\postbuild.bat" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +exit 0 + +:error +echo %command% : failed >> %1\\output.txt 2>&1 +echo %command% : failed +pause +exit 1 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf new file mode 100644 index 00000000..3faa0f34 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/EWARM/stm32wl55xx_flash_cm4.icf @@ -0,0 +1,24 @@ +/*###ICF### Set of symbols used in SE and SB_SFU projects ****/ + +define memory mem with size = 4G; + +/******************************************************************************/ +/* Include of SE symbols file */ +/* (Project>Options>Linker>Extra Options --config_search option is used to */ +/* specify the the directory to search for include files */ +/******************************************************************************/ +include "mapping_sbsfu.icf"; +include "mapping_fwimg.icf"; + +initialize by copy { readwrite }; +do not initialize { section .noinit}; + +/******************************************************************************/ +/* placement instructions */ +/******************************************************************************/ +place at address mem:__ICFEDIT_SE_CallGate_region_ROM_start__ { readonly section .SE_CallGate_Code }; +place at address mem:__ICFEDIT_SE_Startup_region_ROM_start__ { readonly section .SE_Startup_Code}; +place in SE_CODE_NOKEY_ROM_region {readonly}; +place in SE_Key_ROM_region { readonly section .SE_embedded_Keys }; +keep { section .SE_embedded_Keys }; +place in SE_RAM_region {readwrite}; diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/ca_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/ca_conf.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/ca_conf.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/ca_conf.h diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/ca_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/ca_low_level.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/ca_low_level.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/ca_low_level.h diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/kms_config.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_config.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/kms_config.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_config.h diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/kms_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_low_level.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/kms_low_level.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_low_level.h diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/kms_mem_pool_def.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_mem_pool_def.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/kms_mem_pool_def.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_mem_pool_def.h diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/kms_platf_objects_config.h.pattern b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/kms_platf_objects_config.h.pattern rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/kms_platf_objects_interface.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_platf_objects_interface.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/Inc/kms_platf_objects_interface.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/kms_platf_objects_interface.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/mbed_crypto_config.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/mbed_crypto_config.h new file mode 100644 index 00000000..5ea26e4f --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/mbed_crypto_config.h @@ -0,0 +1,1976 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +/* + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CONFIG_H +#define MBEDTLS_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/aria.c + * library/timing.c + * include/mbedtls/bn_mul.h + * + * Required by: + * MBEDTLS_AESNI_C + * MBEDTLS_PADLOCK_C + * + * Comment to disable the use of assembly code. + */ +//#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +//#define MBEDTLS_NO_UDBL_DIVISION + +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +//#define MBEDTLS_NO_64BIT_MULTIPLICATION + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions + */ +//#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). + * The time needs to be correct (not necessarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. + */ +//#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT +//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions so that they generate a warning if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions so that they generate an error if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * Uncomment to get errors on using deprecated functions. + */ +#define MBEDTLS_DEPRECATED_REMOVED + +/** + * \def MBEDTLS_CHECK_PARAMS + * + * This configuration option controls whether the library validates more of + * the parameters passed to it. + * + * When this flag is not defined, the library only attempts to validate an + * input parameter if: (1) they may come from the outside world (such as the + * network, the filesystem, etc.) or (2) not validating them could result in + * internal memory errors such as overflowing a buffer controlled by the + * library. On the other hand, it doesn't attempt to validate parameters whose + * values are fully controlled by the application (such as pointers). + * + * When this flag is defined, the library additionally attempts to validate + * parameters that are fully controlled by the application, and should always + * be valid if the application code is fully correct and trusted. + * + * For example, when a function accepts as input a pointer to a buffer that may + * contain untrusted data, and its documentation mentions that this pointer + * must not be NULL: + * - the pointer is checked to be non-NULL only if this option is enabled + * - the content of the buffer is always validated + * + * When this flag is defined, if a library function receives a parameter that + * is invalid, it will: + * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a + * call to the function mbedtls_param_failed() + * - immediately return (with a specific error code unless the function + * returns void and can't communicate an error). + * + * When defining this flag, you also need to: + * - either provide a definition of the function mbedtls_param_failed() in + * your application (see platform_util.h for its prototype) as the library + * calls that function, but does not provide a default definition for it, + * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED() + * below if the above mechanism is not flexible enough to suit your needs. + * See the documentation of this macro later in this file. + * + * Uncomment to enable validation of application-controlled parameters. + */ +//#define MBEDTLS_CHECK_PARAMS + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + * + * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_ARIA_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT +//#define MBEDTLS_CMAC_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT +//#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT +//#define MBEDTLS_XTEA_ALT + +/* + * When replacing the elliptic curve module, pleace consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT + +/** + * \def MBEDTLS_MD2_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * \note Because of a signature change, the core AES encryption and decryption routines are + * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, + * respectively. When setting up alternative implementations, these functions should + * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * must stay untouched. + * + * \note If you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + * + * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use + * constitutes a security risk. If possible, we recommend avoiding + * dependencies on them, and considering stronger message digests + * and ciphers instead. + * + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT +//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT +//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT +//#define MBEDTLS_ECDSA_VERIFY_ALT +//#define MBEDTLS_ECDSA_SIGN_ALT +//#define MBEDTLS_ECDSA_GENKEY_ALT + +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac + * function, but will use your mbedtls_internal_ecp_double_jac if the group is + * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when + * receives it as an argument). If the group is not supported then the original + * implementation is used. The other functions and the definition of + * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your + * implementation of mbedtls_internal_ecp_double_jac and + * mbedtls_internal_ecp_grp_capable must be compatible with this definition. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +//#define MBEDTLS_TEST_NULL_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Use precomputed AES tables stored in ROM. + * + * Uncomment this macro to use precomputed AES tables stored in ROM. + * Comment this macro to generate AES tables in RAM at runtime. + * + * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb + * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the + * initialization time before the first AES operation can be performed. + * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c + * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded + * performance if ROM access is slower than RAM access. + * + * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + * + */ +//#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_AES_FEWER_TABLES + * + * Use less ROM/RAM for AES tables. + * + * Uncommenting this macro omits 75% of the AES tables from + * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) + * by computing their values on the fly during operations + * (the tables are entry-wise rotations of one another). + * + * Tradeoff: Uncommenting this reduces the RAM / ROM footprint + * by ~6kb but at the cost of more arithmetic operations during + * runtime. Specifically, one has to compare 4 accesses within + * different tables to 4 accesses with additional arithmetic + * operations within the same table. The performance gain/loss + * depends on the system and memory details. + * + * This option is independent of \c MBEDTLS_AES_ROM_TABLES. + * + */ +//#define MBEDTLS_AES_FEWER_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +//#define MBEDTLS_CIPHER_MODE_XTS + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * This module is required to support the TLS ciphersuites that use the NULL + * cipher. + * + * Uncomment this macro to enable the NULL cipher + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +//#define MBEDTLS_CIPHER_PADDING_PKCS7 +//#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +//#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +//#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +//#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +//#define MBEDTLS_ECP_DP_BP256R1_ENABLED +//#define MBEDTLS_ECP_DP_BP384R1_ENABLED +//#define MBEDTLS_ECP_DP_BP512R1_ENABLED +//#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +//#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +//#define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECP_RESTARTABLE + * + * Enable "non-blocking" ECC operations that can return early and be resumed. + * + * This allows various functions to pause by returning + * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in Mbed TLS's SSL module, + * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in order + * to further progress and eventually complete their operation. This is + * controlled through mbedtls_ecp_set_max_ops() which limits the maximum number + * of ECC operations a function may perform before pausing; see + * mbedtls_ecp_set_max_ops() for more information. + * + * This is useful in non-threaded environments if you want to avoid blocking + * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. + * + * Uncomment this macro to enable restartable ECC computations. + * + * \note This option only works with the default software implementation of + * elliptic curve functionality. It is incompatible with + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. + */ +//#define MBEDTLS_ECP_RESTARTABLE + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +//#define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +//#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +//#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +//#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + * + * In PSA key storage, encode the owner of the key. + * + * This is only meaningful when building the library as part of a + * multi-client service. When you activate this option, you must provide + * an implementation of the type psa_key_owner_id_t and a translation + * from psa_key_file_id_t to file name in all the storage backends that + * you wish to support. + * + * Note that this option is meant for internal use only and may be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +//#define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +//#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +//#define MBEDTLS_PKCS1_V21 + +/** + * \def MBEDTLS_PSA_CRYPTO_SPM + * + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure + * Partition Manager) integration which separates the code into two parts: a + * NSPE (Non-Secure Process Environment) and an SPE (Secure Process + * Environment). + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SPM + +/** + * \def MBEDTLS_PSA_INJECT_ENTROPY + * + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. + * + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED + * + */ +//#define MBEDTLS_PSA_INJECT_ENTROPY + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_USE_PSA_CRYPTO + * + * Make the X.509 and TLS library use PSA for cryptographic operations, see + * #MBEDTLS_PSA_CRYPTO_C. + * + * Note: this option is still in progress, the full X.509 and TLS modules are + * not covered yet, but parts that are not ported to PSA yet will still work + * as usual, so enabling this option should not break backwards compatibility. + * + * \warning Support for PSA is still an experimental feature. + * Any public API that depends on this option may change + * at any time until this warning is removed. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + */ +//#define MBEDTLS_USE_PSA_CRYPTO + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +//#define MBEDTLS_VERSION_FEATURES + +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/cipher.c + * library/pem.c + * library/ctr_drbg.c + * + * This module is required to support the TLS ciphersuites that use the AES + * cipher. + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +//#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the ARC4 + * cipher. + * + * \warning ARC4 is considered a weak cipher and its use constitutes a + * security risk. If possible, we recommend avoidng dependencies on + * it, and considering stronger ciphers instead. + * + */ +//#define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +//#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + */ +//#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +//#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/rsa_internal.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +//#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +//#define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * Camellia cipher. + */ +//#define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_ARIA_C + * + * Enable the ARIA block cipher. + * + * Module: library/aria.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * ARIA cipher. + */ +//#define MBEDTLS_ARIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support AES-CCM ciphersuites in TLS. + */ +//#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +//#define MBEDTLS_CHACHA20_C + +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +//#define MBEDTLS_CHACHAPOLY_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * + * Uncomment to enable generic cipher wrappers. + */ +//#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +//#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-based random generator. + * The CTR_DRBG generator uses AES-256 by default. + * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES random number generator. + */ +//#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the DES + * cipher. + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + * + * \warning DES is considered a weak cipher and its use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +//#define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +//#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + */ +//#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +//#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +//#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +//#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support the TLS ciphersuites that use GCM. + */ +//#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +//#define MBEDTLS_HKDF_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +//#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_NIST_KW_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +//#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + * + * \warning MD2 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + * + * \warning MD4 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * + * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 + * depending on the handshake parameters. Further, it is used for checking + * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded + * encrypted keys. + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * + * This modules translates between OIDs and internal values. + */ +//#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +//#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +//#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymmetric) key layer. + * + * Module: library/pk.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +//#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymmetric) key parser. + * + * Module: library/pkparse.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +//#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymmetric) key writer. + * + * Module: library/pkwrite.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +//#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +//#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +//#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +//#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +//#define MBEDTLS_POLY1305_C + +/** + * \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * Module: library/psa_crypto.c + * + * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_C + +/** + * \def MBEDTLS_PSA_CRYPTO_STORAGE_C + * + * Enable the Platform Security Architecture persistent key storage. + * + * Module: library/psa_crypto_storage.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface + */ +//#define MBEDTLS_PSA_CRYPTO_STORAGE_C + +/** + * \def MBEDTLS_PSA_ITS_FILE_C + * + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. + * + * Module: library/psa_its_file.c + * + * Requires: MBEDTLS_FS_IO + */ +//#define MBEDTLS_PSA_ITS_FILE_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +//#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * library/rsa_internal.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +/* #define MBEDTLS_RSA_C */ + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * + * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 + * depending on the handshake parameters, and for SHA1-signed certificates. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-384 and SHA-512. + */ +//#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by Mbed + * TLS's \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and + * provide your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +//#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +//#define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ + +/** + * Uncomment the macro to let mbed TLS use your alternate implementation of + * mbedtls_platform_zeroize(). This replaces the default implementation in + * platform_util.c. + * + * mbedtls_platform_zeroize() is a widely used function across the library to + * zero a block of memory. The implementation is expected to be secure in the + * sense that it has been written to prevent the compiler from removing calls + * to mbedtls_platform_zeroize() as part of redundant code elimination + * optimizations. However, it is difficult to guarantee that calls to + * mbedtls_platform_zeroize() will not be optimized by the compiler as older + * versions of the C language standards do not provide a secure implementation + * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to + * configure their own implementation of mbedtls_platform_zeroize(), for + * example by using directives specific to their compiler, features from newer + * C standards (e.g using memset_s() in C11) or calling a secure memset() from + * their system (e.g explicit_bzero() in BSD). + */ +//#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + +/* \} name SECTION: Customisation configuration options */ + +/* Target and application specific configurations + * + * Allow user to override any previous default. + * + */ +#if defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +#include "mbedtls/check_config.h" + +#endif /* MBEDTLS_CONFIG_H */ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/nvms_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/nvms_low_level.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/nvms_low_level.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/nvms_low_level.h diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/se_crypto_config.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/se_crypto_config.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/se_crypto_config.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/se_crypto_config.h diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/se_def_metadata.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/se_def_metadata.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/se_def_metadata.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/se_def_metadata.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/se_low_level.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/se_low_level.h new file mode 100644 index 00000000..bd8b79e1 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/se_low_level.h @@ -0,0 +1,184 @@ +/** + ****************************************************************************** + * @file se_low_level.h + * @author MCD Application Team + * @brief This file contains definitions for Secure Engine low level interface + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SE_LOW_LEVEL_H +#define SE_LOW_LEVEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "se_def.h" + +/* Secure Engine needs to know the slots configuration for the Read/Write services in protected area + (see @ref SE_IMG_Write, see @ref SE_IMG_Read) */ +#include "sfu_fwimg_regions.h" + +#include "stm32wlxx_hal.h" + +/** @addtogroup SE + * @{ + */ + +/** @addtogroup SE_HARDWARE + * @{ + */ + +/** @defgroup SE_HARDWARE_Exported_Constants Exported Constants + * @{ + */ +/** + * @brief flash handling constants: these constants are used in se_fwimg.c + */ + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Macros Exported Macros + * @{ + */ + +/** @defgroup SE_HARDWARE_Exported_Macros_CRC CRC Settings + * @{ + */ + +/** + * @brief Set CRC 32 of the BootInfoTypeDef pointer passed as parameter + * The CRC is computed with the structure without its CRC field and the length is provided to SE_CRC_Calculate in + * 32-bit word. + * Please note that this works only if the CRC field is kept as the last uint32_t of the SE_BootInfoTypeDef structure. + */ +#define SE_BOOT_CONFIG_SET_CRC_32(x) \ + do{ \ + (x)->CRC32 = SE_CRC_Calculate ((uint32_t*)(x), (sizeof(SE_BootInfoTypeDef)-sizeof(uint32_t))/sizeof(uint32_t));\ + }while(0) + +/** + * @brief Set CRC of the BootInfoTypeDef pointer passed as parameter + */ +#define SE_BOOT_CONFIG_SET_CRC(x) SE_BOOT_CONFIG_SET_CRC_32(x) + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Macros_CodeIsolation Code Isolation Settings + * @brief These settings configure the way the Secure Engine is isolated from the rest of the code. + * @{ + */ + +/** + * MPU : Enter/Exit secured area ==> nothing to do + */ +#define ENTER_PROTECTED_AREA() do { /* do nothing */; } while(0) +#define EXIT_PROTECTED_AREA() do { /* do nothing */; } while(0) + +/** @addtogroup SE_LOW_LEVEL_Exported_Functions + * @{ + */ +void SE_LL_CORE_Cleanup(void); + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Exported_Functions + * @{ + */ + +/** @addtogroup SE_HARDWARE_Exported_CRC_Functions + * @{ + */ +SE_ErrorStatus SE_LL_CRC_Config(void); +SE_ErrorStatus SE_LL_CRC_Init(void); +SE_ErrorStatus SE_LL_CRC_DeInit(void); +uint32_t SE_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t uBufferLength); + +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Exported_FLASH_Functions + * @{ + */ +SE_ErrorStatus SE_LL_FLASH_Erase(uint8_t *pStart, uint32_t Length); +SE_ErrorStatus SE_LL_FLASH_Write(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); +SE_ErrorStatus SE_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length); + +void NMI_Handler(void); +void HardFault_Handler(void); +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Exported_FLASH_EXT_Functions + * @{ + */ +SE_ErrorStatus SE_LL_FLASH_EXT_Decrypt_Init(SE_FwRawHeaderTypeDef *pxSE_Metadata); +/** + * @} + */ + +/** @addtogroup SE_BUFFER_CHECK_Exported_RAM_Functions + * @{ + */ + +SE_ErrorStatus SE_LL_Buffer_in_ram(void *pBuff, uint32_t Length); +SE_ErrorStatus SE_LL_Buffer_in_SBSFU_ram(const void *pBuff, uint32_t Length); +SE_ErrorStatus SE_LL_Buffer_part_of_SE_ram(const void *pBuff, uint32_t Length); +SE_ErrorStatus SE_LL_Buffer_part_of_SE_rom(const void *pBuff, uint32_t Length); +/** + * @} + */ + +/** @addtogroup SE_LOCK_KEYS_Exported_Functions + * @{ + */ +SE_ErrorStatus SE_LL_Lock_Keys(void); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SE_LOW_LEVEL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/stm32wlxx_hal_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Inc/stm32wlxx_hal_conf.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/Project.uvoptx new file mode 100644 index 00000000..790df77b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/Project.uvoptx @@ -0,0 +1,701 @@ + + + + 1.0 + +
      ### uVision Project, (C) Keil Software
      + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32WL55JC_Nucleo_1_Image_SECoreBin + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + ST-LINKIII-KEIL_SWO + -U001F00313038511234333935 -O206 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4.FLM -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + + + + 1 + 0 + 0x20005AF8 + 0 + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\data_init.c + data_init.c + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ../Src/ca_low_level.c + ca_low_level.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ../Src/kms_low_level.c + kms_low_level.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ../Src/nvms_low_level.c + nvms_low_level.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ../Src/se_low_level.c + se_low_level.c + 0 + 0 + + + + + Doc + 1 + 0 + 0 + 0 + + 3 + 6 + 5 + 0 + 0 + 0 + ../readme.txt + readme.txt + 0 + 0 + + + + + Drivers/STM32WLxx_HAL_Driver + 0 + 0 + 0 + 0 + + 4 + 7 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + stm32wlxx_hal_crc.c + 0 + 0 + + + 4 + 8 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + stm32wlxx_hal_crc_ex.c + 0 + 0 + + + 4 + 9 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c + stm32wlxx_hal_cryp.c + 0 + 0 + + + 4 + 10 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c + stm32wlxx_hal_cryp_ex.c + 0 + 0 + + + 4 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_dma.c + stm32wlxx_hal_dma.c + 0 + 0 + + + 4 + 12 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + stm32wlxx_hal_flash.c + 0 + 0 + + + 4 + 13 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + stm32wlxx_hal_flash_ex.c + 0 + 0 + + + 4 + 14 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c + stm32wlxx_hal_pka.c + 0 + 0 + + + + + Middlewares/STM32_Secure_Engine + 0 + 0 + 0 + 0 + + 5 + 15 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c + se_callgate.c + 0 + 0 + + + 5 + 16 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c + se_exception.c + 0 + 0 + + + 5 + 17 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c + se_fwimg.c + 0 + 0 + + + 5 + 18 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c + se_startup.c + 0 + 0 + + + 5 + 19 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c + se_user_application.c + 0 + 0 + + + 5 + 20 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c + se_utils.c + 0 + 0 + + + + + Middlewares/STM32_Key_Management_Services + 0 + 0 + 0 + 0 + + 6 + 21 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c + ca_core.c + 0 + 0 + + + 6 + 22 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c + kms_der_x962.c + 0 + 0 + + + 6 + 23 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c + kms_digest.c + 0 + 0 + + + 6 + 24 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c + kms_dyn_obj.c + 0 + 0 + + + 6 + 25 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c + kms_ecc.c + 0 + 0 + + + 6 + 26 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c + kms_enc_dec.c + 0 + 0 + + + 6 + 27 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c + kms_entry.c + 0 + 0 + + + 6 + 28 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c + kms_init.c + 0 + 0 + + + 6 + 29 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c + kms_key_mgt.c + 0 + 0 + + + 6 + 30 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c + kms_mem.c + 0 + 0 + + + 6 + 31 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c + kms_nvm_storage.c + 0 + 0 + + + 6 + 32 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c + kms_objects.c + 0 + 0 + + + 6 + 33 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c + kms_platf_objects.c + 0 + 0 + + + 6 + 34 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c + kms_sign_verify.c + 0 + 0 + + + + + Middlewares/Third_Party/mbed-crypto + 0 + 0 + 0 + 0 + + 7 + 35 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/platform_util.c + platform_util.c + 0 + 0 + + + 7 + 36 + 1 + 0 + 0 + 0 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/sha256.c + sha256.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..46bcfce1 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/Project.uvprojx @@ -0,0 +1,619 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_SECoreBin + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + SECoreBin + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 1 + + prebuild.bat . + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf #L --bin --output=$L@L.bin + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED,MBEDTLS_CONFIG_FILE=<mbed_crypto_config.h>,IT_MANAGEMENT_DISABLED + + .;../Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../../../../../Middlewares/ST/STM32_Secure_Engine/Key;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules;../../../../../../Middlewares/Third_Party/mbed-crypto/include;../../1_Image_BFU/BFU/App;../../1_Image_BFU/BFU/Target;../../Linker_Common/MDK-ARM + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + SECoreBin.sct + + + --entry=SE_CallGate +--diag_suppress L6404W +--diag_suppress L6314W + + + + + + + + Application/MDK-ARM + + + data_init.c + 1 + .\data_init.c + + + + + Application/User + + + ca_low_level.c + 1 + ../Src/ca_low_level.c + + + kms_low_level.c + 1 + ../Src/kms_low_level.c + + + nvms_low_level.c + 1 + ../Src/nvms_low_level.c + + + se_low_level.c + 1 + ../Src/se_low_level.c + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Drivers/STM32WLxx_HAL_Driver + + + stm32wlxx_hal_crc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + stm32wlxx_hal_crc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + stm32wlxx_hal_cryp.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c + + + stm32wlxx_hal_cryp_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c + + + stm32wlxx_hal_dma.c + 1 + ..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_dma.c + + + stm32wlxx_hal_flash.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + stm32wlxx_hal_flash_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + stm32wlxx_hal_pka.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c + + + + + Middlewares/STM32_Secure_Engine + + + se_callgate.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c + + + se_exception.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c + + + se_fwimg.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c + + + se_startup.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c + + + se_user_application.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c + + + se_utils.c + 1 + ../../../../../../Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c + + + + + Middlewares/STM32_Key_Management_Services + + + ca_core.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c + + + kms_der_x962.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c + + + kms_digest.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c + + + kms_dyn_obj.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c + + + kms_ecc.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c + + + kms_enc_dec.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c + + + kms_entry.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c + + + kms_init.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c + + + kms_key_mgt.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c + + + kms_mem.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c + + + kms_nvm_storage.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c + + + kms_objects.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c + + + kms_platf_objects.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c + + + kms_sign_verify.c + 1 + ../../../../../../Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c + + + + + Middlewares/Third_Party/mbed-crypto + + + platform_util.c + 1 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/platform_util.c + + + sha256.c + 1 + ../../../../../../Middlewares/Third_Party/mbed-crypto/library/sha256.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat new file mode 100644 index 00000000..db1d9d8c --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM.bat @@ -0,0 +1,122 @@ +::Post build for SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfu=%userAppBinary%\\%execname%.sfu" +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" + + +set "nonce=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\nonce.bin" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\MDK-ARM\\STM32WL55JC_Nucleo\\Exe\\BFU.axf" +set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_GCM.bin" +set "magic=SFU%fwid%" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +set "command=%python%%prepareimage% enc -k %oemkey% -n %nonce% %bin% %sfu% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sign -k %oemkey% -n %nonce% %bin% %sign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% %sfb% -o 512 >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %oemkey% -r 112 -v %version% -n %nonce% -f %sfu% -t %sign% -o 512 %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat new file mode 100644 index 00000000..dced100d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256.bat @@ -0,0 +1,119 @@ +::Post build for SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" + +set "oemkey=" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\MDK-ARM\\STM32WL55JC_Nucleo\\Exe\\BFU.axf" +set "magic=SFU%fwid%" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" > %projectdir%\output.txt 2>&1 +IF %ERRORLEVEL% NEQ 0 goto :error +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +:: no encryption +set "command=%python%%prepareimage% sha256 %bin% %sign% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:: no encryption so pack the binary file + +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% %sfb% -o 512 >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -p 1 -r 44 -v %version% -f %bin% -t %sign% -o 512 %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat new file mode 100644 index 00000000..aff8ddbb --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256.bat @@ -0,0 +1,121 @@ +::Post build for SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfu=%userAppBinary%\\%execname%.sfu" +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" + +set "iv=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\iv.bin" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\MDK-ARM\\STM32WL55JC_Nucleo\\Exe\\BFU.axf" +set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_CBC.bin" +set "magic=SFU%fwid%" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +set "command=%python%%prepareimage% enc -k %oemkey% -i %iv% %bin% %sfu% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sha256 %bin% %sign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% %sfb% -o 512 >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% -o 512 %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct new file mode 100644 index 00000000..a5aba32a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/SECoreBin.sct @@ -0,0 +1,26 @@ +#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0plus -E -xc +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* +#include "..\..\Linker_Common\MDK-ARM\mapping_sbsfu.h" +#include "..\..\Linker_Common\MDK-ARM\mapping_fwimg.h" + + +; *** regions needed by SE_CoreBin project *** +LR_SE SE_CODE_REGION_ROM_START { + SE_CallGate_region_ROM SE_CALLGATE_REGION_ROM_START FIXED SE_CALLGATE_REGION_ROM_SIZE { + *(.SE_CallGate_Code) + } + SE_Key_region_ROM SE_KEY_REGION_ROM_START FIXED SE_KEY_REGION_ROM_SIZE { + *(.SE_embedded_Keys) + } + SE_Startup_region_ROM SE_STARTUP_REGION_ROM_START FIXED { + *(.SE_Startup_Code) + } + SE_Code_NoKey_region SE_CODE_NOKEY_REGION_ROM_START FIXED SE_ROM_REGION_SIZE{ + .ANY (+RO) + } + SE_region_RAM SE_REGION_RAM_STACK_TOP SE_RAM_REGION_SIZE { + .ANY (+RW +ZI) + } +} diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/MDK-ARM/data_init.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/data_init.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/MDK-ARM/data_init.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/data_init.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/postbuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/postbuild.bat new file mode 100644 index 00000000..aff8ddbb --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/postbuild.bat @@ -0,0 +1,121 @@ +::Post build for SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 +:: arg1 is the build directory +:: arg2 is the elf file path+name +:: arg3 is the bin file path+name +:: arg4 is the firmware Id (1/2/3) +:: arg5 is the version +:: arg6 when present forces "bigelf" generation +@echo off +set "projectdir=%1" +set "execname=%~n3" +set "elf=%2" +set "bin=%3" +set "fwid=%4" +set "version=%5" + +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::The default installation path of the Cube Programmer tool is: "C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin" +::If you installed it in another location, please update the %programmertool% variable below accordingly. +set "programmertool="C:\\Program Files\\STMicroelectronics\\STM32Cube\\STM32CubeProgrammer\\bin\\STM32_Programmer_CLI"" +set "userAppBinary=%projectdir%\\..\\Binary\\" + +set "sfu=%userAppBinary%\\%execname%.sfu" +set "sfb=%userAppBinary%\\%execname%.sfb" +set "sign=%userAppBinary%\\%execname%.sign" +set "headerbin=%userAppBinary%\\%execname%sfuh.bin" +set "bigbinary=%userAppBinary%\\BFU_%execname%.bin" +set "elfbackup=%userAppBinary%\\SBSFU_%execname%.elf" + +set "iv=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\iv.bin" +set "ecckey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\ECCKEY%fwid%.txt" +set "sbsfuelf=%SBSFUBootLoader%\\1_Image_BFU\\MDK-ARM\\STM32WL55JC_Nucleo\\Exe\\BFU.axf" +set "oemkey=%SBSFUBootLoader%\\1_Image_SECoreBin\\Binary\\OEM_KEY_COMPANY%fwid%_key_AES_CBC.bin" +set "magic=SFU%fwid%" + +::comment this line to force python +::python is used if windows executable not found +pushd %projectdir%\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Postbuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto postbuild +) +:py +::line for python +echo Postbuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +:postbuild + +::Make sure we have a Binary sub-folder in UserApp folder +if not exist "%userAppBinary%" ( +mkdir "%userAppBinary%" +) + +::PostBuild is fired if elf has been regenerated from last run, so elf is different from backup elf +if exist %elfbackup% ( +fc %elfbackup% %elf% >NUL && (goto nothingtodo) || echo "elf has been modified, processing required" +) + +set "command=%python%%prepareimage% enc -k %oemkey% -i %iv% %bin% %sfu% > %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% sha256 %bin% %sign% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% pack -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% %sfb% -o 512 >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=%python%%prepareimage% header -m %magic% -k %ecckey% -r 28 -v %version% -i %iv% -f %sfu% -t %sign% -o 512 %headerbin% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +set "command=%python%%prepareimage% merge -i %headerbin% -s %sbsfuelf% -u %elf% %bigbinary% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + + +:bigelf +IF "%~6"=="" goto :finish +echo "Generating the global elf file (SBSFU and userApp)" +echo "Generating the global elf file (SBSFU and userApp)" >> %projectdir%\output.txt +set "command=%programmertool% -ms %elf% %headerbin% %sbsfuelf% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error +set "command=copy %elf% %elfbackup% >> %projectdir%\output.txt 2>&1" +%command% +IF %ERRORLEVEL% NEQ 0 goto :error + +:finish +::backup and clean up the intermediate file +del %sign% +del %sfu% +del %headerbin% + +exit 0 + +:error +echo "%command% : failed" >> %projectdir%\\output.txt +:: remove the elf to force the regeneration +if exist %elf%( + del %elf% +) +if exist %elfbackup%( + del %elfbackup% +) +echo %command% : failed + +pause +exit 1 + +:nothingtodo +exit 0 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/prebuild.bat b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/prebuild.bat new file mode 100644 index 00000000..4e8662aa --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/MDK-ARM/prebuild.bat @@ -0,0 +1,147 @@ +@echo off +echo prebuild.bat : started > %1\\output.txt +set "SBSFUBootLoader=%~d0%~p0\\..\\.." +::comment this line to force python +::python is used if windows executable not found +pushd %1\..\..\..\..\..\..\Middlewares\ST\STM32_Secure_Engine\Utilities\KeysAndImages +set basedir=%cd% +popd +goto exe: +goto py: +:exe +::line for window executable +echo Prebuild with windows executable +set "prepareimage=%basedir%\\win\\prepareimage.exe" +set "python=" +if exist %prepareimage% ( +goto prebuild +) +:py +::line for python +echo Prebuild with python script +set "prepareimage=%basedir%\\prepareimage.py" +set "python=python " +echo "python: %prepareimage%" >> %1\\output.txt 2>>&1 +:prebuild +set "crypto_h=%1\\..\\Inc\\se_crypto_config.h" + +::clean +if exist %1\\crypto.txt ( + del %1\\crypto.txt +) + +if exist %1\\postbuild.bat ( + del %1\\postbuild.bat +) + +::get crypto name +set "command=%python%%prepareimage% conf %crypto_h% > %1\\crypto.txt" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set /P crypto=<%1\\crypto.txt >> %1\\output.txt 2>>&1 +echo crypto %crypto% selected >> %1\\output.txt 2>>&1 + +set "cortex=V7M" + +set "KMS_config=%1\kms_platf_objects_config.h" +set "KMS_tmp=%1\kms_platf_objects_config.h.tmp" + +::Patch KMS embedded keys with Blob Keys +set "kmsblob_ecckey=%SBSFUBootLoader%\\1_Image_KMS_Blob\\Binary\\ECCKEY.txt" +set "command=%python%%prepareimage% inject -k %kmsblob_ecckey% -f %1\..\Inc\kms_platf_objects_config.h.pattern -p @ECDSA_BLOB_KEY@ %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "kmsblob_oemkey=%SBSFUBootLoader%\\1_Image_KMS_Blob\\Binary\\OEM_KEY_COMPANY1_key_AES_CBC.bin" +set "command=%python%%prepareimage% inject -k %kmsblob_oemkey% -f %KMS_tmp% -p @AES_BLOB_KEY@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +if "%crypto%"=="SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM" ( + set "type=GCM" + goto AES128 +) +if "%crypto%"=="SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256" ( + set "type=CBC" + goto AES128 +) +::For KMS dummy AES keys are needed (reusing AES_CBC inputs files) +if "%crypto%"=="SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256" ( + set "type=CBC" + goto AES128 +) +goto end + +:AES128 +set "oemkey=%1\\..\\Binary\\OEM_KEY_COMPANY1_key_AES_%type%.bin" +set "command=%python%%prepareimage% inject -k %oemkey% -f %KMS_tmp% -p @AES_SBSFU_KEY_1@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "oemkey=%1\\..\\Binary\\OEM_KEY_COMPANY2_key_AES_%type%.bin" +IF NOT EXIST %oemkey% goto AES128_end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %oemkey% -f %KMS_tmp% -p @AES_SBSFU_KEY_2@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "oemkey=%1\\..\\Binary\\OEM_KEY_COMPANY3_key_AES_%type%.bin" +IF NOT EXIST %oemkey% goto AES128_end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %oemkey% -f %KMS_tmp% -p @AES_SBSFU_KEY_3@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +:AES128_end +::For KMS dummy ECC keys are needed +::if "%crypto%"=="SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM" goto end +goto ECDSA + +:ECDSA +set "ecckey=%1\\..\\Binary\\ECCKEY1.txt" +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %ecckey% -f %KMS_tmp% -p @ECDSA_SBSFU_KEY_1@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "ecckey=%1\\..\\Binary\\ECCKEY2.txt" +IF NOT EXIST %ecckey% goto end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %ecckey% -f %KMS_tmp% -p @ECDSA_SBSFU_KEY_2@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +set "ecckey=%1\\..\\Binary\\ECCKEY3.txt" +IF NOT EXIST %ecckey% goto end +set "command=copy %KMS_config% %KMS_tmp%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +set "command=%python%%prepareimage% inject -k %ecckey% -f %KMS_tmp% -p @ECDSA_SBSFU_KEY_3@ %KMS_config%" +%command% +IF %ERRORLEVEL% NEQ 0 goto error + +goto end + + +:end +del %KMS_tmp% +set "command=copy %1\\%crypto%.bat %1\\postbuild.bat" +%command% +IF %ERRORLEVEL% NEQ 0 goto error +exit 0 + +:error +echo %command% : failed >> %1\\output.txt 2>&1 +echo %command% : failed +pause +exit 1 diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/.cproject new file mode 100644 index 00000000..8c2f37a9 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/.cproject @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/.project new file mode 100644 index 00000000..e65aa4fa --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/.project @@ -0,0 +1,201 @@ + + + 1_Image_SECoreBin + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doc/readme.txt + 1 + $%7BPARENT-1-PROJECT_LOC%7D/readme.txt + + + Application/User/ca_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/ca_low_level.c + + + Application/User/kms_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/kms_low_level.c + + + Application/User/nvms_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/nvms_low_level.c + + + Application/User/se_low_level.c + 1 + $%7BPARENT-1-PROJECT_LOC%7D/Src/se_low_level.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cryp.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cryp_ex.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cryp_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pka.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pka.c + + + Middlewares/STM32_Key_Management_Services/ca_core.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Interface/CryptoApi/ca_core.c + + + Middlewares/STM32_Key_Management_Services/kms_der_x962.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_der_x962.c + + + Middlewares/STM32_Key_Management_Services/kms_digest.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_digest.c + + + Middlewares/STM32_Key_Management_Services/kms_dyn_obj.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_dyn_obj.c + + + Middlewares/STM32_Key_Management_Services/kms_ecc.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_ecc.c + + + Middlewares/STM32_Key_Management_Services/kms_enc_dec.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_enc_dec.c + + + Middlewares/STM32_Key_Management_Services/kms_entry.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_entry.c + + + Middlewares/STM32_Key_Management_Services/kms_init.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_init.c + + + Middlewares/STM32_Key_Management_Services/kms_key_mgt.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_key_mgt.c + + + Middlewares/STM32_Key_Management_Services/kms_mem.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_mem.c + + + Middlewares/STM32_Key_Management_Services/kms_nvm_storage.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_nvm_storage.c + + + Middlewares/STM32_Key_Management_Services/kms_objects.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_objects.c + + + Middlewares/STM32_Key_Management_Services/kms_platf_objects.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Core/kms_platf_objects.c + + + Middlewares/STM32_Key_Management_Services/kms_sign_verify.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Key_Management_Services/Modules/kms_sign_verify.c + + + Middlewares/STM32_Secure_Engine/se_callgate.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_callgate.c + + + Middlewares/STM32_Secure_Engine/se_exception.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_exception.c + + + Middlewares/STM32_Secure_Engine/se_fwimg.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_fwimg.c + + + Middlewares/STM32_Secure_Engine/se_startup.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_startup.c + + + Middlewares/STM32_Secure_Engine/se_user_application.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_user_application.c + + + Middlewares/STM32_Secure_Engine/se_utils.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/ST/STM32_Secure_Engine/Core/se_utils.c + + + Middlewares/Third_Party/mbed-crypto/sha256.c + 1 + $%7BPARENT-6-PROJECT_LOC%7D/Middlewares/Third_Party/mbed-crypto/library/sha256.c + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/Application/Startup/data_init.c diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_End_Node/STM32CubeIDE/Application/Core/syscalls.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/Application/User/syscalls.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN/LoRaWAN_End_Node/STM32CubeIDE/Application/Core/syscalls.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/Application/User/syscalls.c diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM4/Application/User/sysmem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/Application/User/sysmem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM4/Application/User/sysmem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/Application/User/sysmem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld new file mode 100644 index 00000000..3cb3b060 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/STM32CubeIDE/SECoreBin.ld @@ -0,0 +1,152 @@ +/* +** LinkerScript +*/ + +/* Entry Point */ +ENTRY(SE_CallGate) + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0; /* specific stack provided inside secured area */ + +INCLUDE mapping_fwimg.ld +INCLUDE mapping_sbsfu.ld + +/* Define output sections */ +SECTIONS +{ + .SE_CallGate_Code : + { + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + BYTE(0); /* dummy byte to keep the callgate at 0x8000204 */ + KEEP(*(.SE_CallGate_Code)) + } > SE_CallGate_ROM_region + + .SE_embedded_Keys : { KEEP(*(.SE_embedded_Keys)) } > SE_Key_region_ROM + + .SE_Startup_Code : { KEEP ( *se_startup.o (.text .text*)) } > SE_Startup_ROM_region + .text : + { + . = ALIGN(8); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(8); + _etext = .; /* define a global symbols at end of code */ + } >SE_Code_NoKey_ROM_region + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .ARM.extab : + { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >SE_Code_NoKey_ROM_region + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + } >SE_RAM_region AT>SE_Code_NoKey_ROM_region + + + /* Uninitialized data section */ + . = ALIGN(8); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >SE_RAM_region + + /* User_heap_stack section, used to check that there is enough "SRAM1" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SE_RAM_region + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/ca_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/ca_low_level.c new file mode 100644 index 00000000..30759a90 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/ca_low_level.c @@ -0,0 +1,255 @@ +/** + ****************************************************************************** + * @file ca_low_level.c + * @author MCD Application Team + * @brief This file contains the low level implementations of the Cryptographic API (CA) module. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef CA_LOW_LEVEL_C +#define CA_LOW_LEVEL_C + +/* Includes ------------------------------------------------------------------*/ +#include "CryptoApi/ca.h" +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +#include "mbedtls/entropy_poll.h" +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ + +/* Private defines -----------------------------------------------------------*/ +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +#define COMPILER_BARRIER() __DMB();__DSB(); +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ +/* Private typedef -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +static RNG_HandleTypeDef handle; +static uint8_t users = 0; +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ +/* Private function prototypes -----------------------------------------------*/ +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +static uint8_t atomic_incr_u8(__IO uint8_t *valuePtr, uint8_t delta); +static void RNG_Init(void); +static void RNG_GetBytes(uint8_t *output, size_t length, size_t *output_length); +static void RNG_DeInit(void); +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ + +/* Exported functions implementation -----------------------------------------*/ + +#if defined(CA_HAL_CRYPTOLIB_SUPP) + +#if ((CA_ROUTE_AES_CBC & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_CCM & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_CMAC & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_ECB & CA_ROUTE_MASK) == CA_ROUTE_HAL) \ + || ((CA_ROUTE_AES_GCM & CA_ROUTE_MASK) == CA_ROUTE_HAL) + +/** + * @brief CRYP MSP Initialization + * This function configures the hardware resources + * @param hcryp: CRYP handle pointer + * @retval None + */ +void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp) +{ + if (hcryp->Instance == CA_AES_INSTANCE) + { + /* Release AES/CRYP from reset state */ + __HAL_RCC_AES_RELEASE_RESET(); + /* Peripheral clock enable */ + __HAL_RCC_AES_CLK_ENABLE(); + } +} + +/** + * @brief CRYP MSP De-Initialization + * This function freeze the hardware resources + * @param hcryp: CRYP handle pointer + * @retval None + */ +void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp) +{ + if (hcryp->Instance == CA_AES_INSTANCE) + { + /* Peripheral clock disable */ + __HAL_RCC_AES_CLK_DISABLE(); + /* Force AES/CRYP into reset state */ + __HAL_RCC_AES_FORCE_RESET(); + } +} +#endif /* CA_ROUTE_AES_CBC || CA_ROUTE_AES_CCM || CA_ROUTE_AES_CMAC \ + || CA_ROUTE_AES_ECB || CA_ROUTE_AES_GCM => CA_ROUTE_HAL */ + + +#if ((CA_ROUTE_ECC_ECDSA & CA_ROUTE_MASK) == CA_ROUTE_HAL) || ((CA_ROUTE_RSA & CA_ROUTE_MASK) == CA_ROUTE_HAL) +/** + * @brief PKA MSP Initialization + * This function configures the hardware resources used in this example + * @param[in] hpka: PKA handle pointer + * @retval None + */ +void HAL_PKA_MspInit(PKA_HandleTypeDef *hpka) +{ + if (hpka->Instance == CA_PKA_INSTANCE) + { + /* Release PKA from reset state */ + __HAL_RCC_PKA_RELEASE_RESET(); + /* Peripheral clock enable */ + __HAL_RCC_PKA_CLK_ENABLE(); + } +} + +/** + * @brief PKA MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param[in] hpka: PKA handle pointer + * @retval None + */ +void HAL_PKA_MspDeInit(PKA_HandleTypeDef *hpka) +{ + if (hpka->Instance == CA_PKA_INSTANCE) + { + /* Peripheral clock disable */ + __HAL_RCC_PKA_CLK_DISABLE(); + /* Force PKA into reset state */ + __HAL_RCC_PKA_FORCE_RESET(); + } +} +#endif /* CA_ROUTE_ECC_ECDSA || CA_ROUTE_RSA => CA_ROUTE_HAL */ + +#endif /* CA_HAL_CRYPTOLIB_SUPP */ + +#if defined(CA_MBED_CRYPTOLIB_SUPP) +#if defined(CA_USES_PSA_CRYPTO) && defined(HAL_RNG_MODULE_ENABLED) +static uint8_t atomic_incr_u8(__IO uint8_t *valuePtr, uint8_t delta) +{ + COMPILER_BARRIER(); + uint8_t newValue; + do + { + newValue = __LDREXB(valuePtr) + delta; + } while (__STREXB(newValue, valuePtr)); + COMPILER_BARRIER(); + return newValue; +} + +static void RNG_Init(void) +{ + uint32_t dummy; + + /* We're only supporting a single user of RNG */ + if (atomic_incr_u8(&users, 1) > 1) + { + while (1); + } + + /* Select MSI as RNG clock source */ + __HAL_RCC_RNG_CONFIG(RCC_RNGCLKSOURCE_MSI); + + /* RNG Peripheral clock enable */ + __HAL_RCC_RNG_CLK_ENABLE(); + + /* Initialize RNG instance */ + handle.Instance = RNG; + handle.State = HAL_RNG_STATE_RESET; + handle.Lock = HAL_UNLOCKED; + + HAL_RNG_Init(&handle); + + /* first random number generated after setting the RNGEN bit should not be used */ + HAL_RNG_GenerateRandomNumber(&handle, &dummy); +} + +static void RNG_GetBytes(uint8_t *output, size_t length, size_t *output_length) +{ + int32_t ret = 0; + __IO uint8_t random[4]; + *output_length = 0; + + /* Get Random byte */ + while ((*output_length < length) && (ret == 0)) + { + if (HAL_RNG_GenerateRandomNumber(&handle, (uint32_t *)random) != HAL_OK) + { + ret = -1; + } + else + { + for (uint8_t i = 0; (i < 4) && (*output_length < length) ; i++) + { + *output++ = random[i]; + *output_length += 1; + random[i] = 0; + } + } + } + /* Just be extra sure that we didn't do it wrong */ + if ((__HAL_RNG_GET_FLAG(&handle, (RNG_FLAG_CECS | RNG_FLAG_SECS))) != 0) + { + *output_length = 0; + } +} + +static void RNG_DeInit(void) +{ + /*Disable the RNG peripheral */ + HAL_RNG_DeInit(&handle); + /* RNG Peripheral clock disable - assume we're the only users of RNG */ + __HAL_RCC_RNG_CLK_DISABLE(); + + users = 0; +} + +int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) +{ + RNG_Init(); + RNG_GetBytes(output, len, olen); + RNG_DeInit(); + if (*olen != len) + { + return -1; + } + return 0; +} +#endif /* CA_USES_PSA_CRYPTO && HAL_RNG_MODULE_ENABLED */ +#endif /* CA_MBED_CRYPTOLIB_SUPP */ + +#if defined(CA_ST_CRYPTOLIB_SUPP) +/** + * @brief CRC initialization + * This function release reset and clock CRC IP peripheral + * @retval None + */ +void CA_LL_CRC_Init(void) +{ + /* Force CRC into reset state */ + __HAL_RCC_CRC_FORCE_RESET(); + /* Release CRC from reset state */ + __HAL_RCC_CRC_RELEASE_RESET(); + /* Peripheral clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); +} + +#endif /* CA_ST_CRYPTOLIB_SUPP */ + +#endif /* CA_LOW_LEVEL_C */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Src/kms_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/kms_low_level.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Src/kms_low_level.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/kms_low_level.c diff --git a/Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Src/nvms_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/nvms_low_level.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/LoRaWAN_FUOTA/2_Images_SECoreBin/Src/nvms_low_level.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/nvms_low_level.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/se_low_level.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/se_low_level.c new file mode 100644 index 00000000..cfec9ebf --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/Src/se_low_level.c @@ -0,0 +1,706 @@ +/** + ****************************************************************************** + * @file se_low_level.c + * @author MCD Application Team + * @brief Secure Engine Interface module. + * This file provides set of firmware functions to manage SE low level + * interface functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define SE_LOW_LEVEL_C + +/* Includes ------------------------------------------------------------------*/ +#include "se_low_level.h" +#if defined(__ARMCC_VERSION) +#include "mapping_sbsfu.h" +#endif /* __CC_ARM */ +#include "se_exception.h" +#include "string.h" + +#ifdef KMS_ENABLED +#include "kms.h" +#include "kms_objects.h" +#include "kms_platf_objects_config.h" +#endif /* KMS_ENABLED */ + +/** @addtogroup SE Secure Engine + * @{ + */ +/** @defgroup SE_HARDWARE SE Hardware Interface + * @{ + */ + +/** @defgroup SE_HARDWARE_Private_Variables Private Variables + * @{ + */ +static CRC_HandleTypeDef CrcHandle; /*!< SE Crc Handle*/ + +static __IO uint32_t SE_DoubleECC_Error_Counter = 0U; + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Private_Functions Private Functions + * @{ + */ + +static uint32_t SE_LL_GetPage(uint32_t Address); +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Variables Exported Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_Functions Exported Functions + * @{ + */ + +/** @defgroup SE_HARDWARE_Exported_CRC_Functions CRC Exported Functions + * @{ + */ + +/** + * @brief Set CRC configuration and call HAL CRC initialization function. + * @param None. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise + */ +SE_ErrorStatus SE_LL_CRC_Config(void) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + CrcHandle.Instance = CRC; + /* The input data are not inverted */ + CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + + /* The output data are not inverted */ + CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + + /* The Default polynomial is used */ + CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + /* The default init value is used */ + CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + /* The input data are 32-bit long words */ + CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_WORDS; + /* CRC Init*/ + if (HAL_CRC_Init(&CrcHandle) == HAL_OK) + { + e_ret_status = SE_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief Wrapper to HAL CRC initialization function. + * @param None + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_CRC_Init(void) +{ + /* CRC Peripheral clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + + return SE_LL_CRC_Config(); +} + +/** + * @brief Wrapper to HAL CRC de-initialization function. + * @param None + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_CRC_DeInit(void) +{ + SE_ErrorStatus e_ret_status = SE_ERROR; + + if (HAL_CRC_DeInit(&CrcHandle) == HAL_OK) + { + /* Initialization OK */ + e_ret_status = SE_SUCCESS; + } + + return e_ret_status; +} + +/** + * @brief Wrapper to HAL CRC Calculate function. + * @param pBuffer: pointer to data buffer. + * @param uBufferLength: buffer length in 32-bits word. + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +uint32_t SE_LL_CRC_Calculate(uint32_t pBuffer[], uint32_t uBufferLength) +{ + return HAL_CRC_Calculate(&CrcHandle, pBuffer, uBufferLength); +} + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_FLASH_Functions FLASH Exported Functions + * @{ + */ + +/** + * @brief This function does an erase of nb pages in user flash area + * @param pStart: pointer to user flash area + * @param Length: number of bytes. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_FLASH_Erase(uint8_t *pStart, uint32_t Length) +{ + uint32_t page_error = 0U; + uint32_t start = (uint32_t)pStart; + FLASH_EraseInitTypeDef p_erase_init; + SE_ErrorStatus e_ret_status = SE_SUCCESS; + + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + /* Fill EraseInit structure*/ + p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + p_erase_init.Page = SE_LL_GetPage(start); + p_erase_init.NbPages = SE_LL_GetPage(start + Length - 1U) - p_erase_init.Page + 1U; + if (HAL_FLASHEx_Erase(&p_erase_init, &page_error) != HAL_OK) + { + e_ret_status = SE_ERROR; + } + + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + (void)HAL_FLASH_Lock(); + } + else + { + e_ret_status = SE_ERROR; + } + + return e_ret_status; +} + +/** + * @brief Write in Flash protected area + * @param pDestination pointer to destination area in Flash + * @param pSource pointer to input buffer + * @param Length number of bytes to be written + * @retval SE_SUCCESS if successful, otherwise SE_ERROR + */ + +SE_ErrorStatus SE_LL_FLASH_Write(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + SE_ErrorStatus ret = SE_SUCCESS; + uint32_t i; + uint32_t verified = 0U; + uint32_t destination = (uint32_t)pDestination; + uint32_t source = (uint32_t)pSource; + + if (Length == 0U) + { + return SE_ERROR; + } + + /* Area should be inside 1 of the firmware image headers */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((destination >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((destination + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + verified = 1U; + } + } + if (verified == 0U) + { + return SE_ERROR; + } + + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + for (i = 0U; i < Length; i += 8U) + { + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (destination + i), *(uint64_t *)(source + i)) != HAL_OK) + { + ret = SE_ERROR; + break; + } + } + + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) */ + (void)HAL_FLASH_Lock(); + } + else + { + ret = SE_ERROR; + } + return ret; +} + +/** + * @brief Read in Flash protected area + * @param pDestination: Start address for target location + * @param pSource: pointer on buffer with data to read + * @param Length: Length in bytes of data buffer + * @retval SFU_ErrorStatus SFU_SUCCESS if successful, SFU_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_FLASH_Read(uint8_t *pDestination, const uint8_t *pSource, uint32_t Length) +{ + uint32_t source = (uint32_t)pSource; + SE_ErrorStatus e_ret_status = SE_ERROR; + uint32_t i; + uint32_t verified = 0U; + + /* Area should be inside 1 of the firmware image headers + or inside 1 of the download areas */ + for (i = 0U; i < SFU_NB_MAX_ACTIVE_IMAGE; i++) + { + if ((source >= SlotHeaderAdd[SLOT_ACTIVE_1 + i]) && + ((source + Length) <= (SlotHeaderAdd[SLOT_ACTIVE_1 + i] + SFU_IMG_IMAGE_OFFSET))) + { + verified = 1U; + } + } + + for (i = 0U; i < SFU_NB_MAX_DWL_AREA; i++) + { + if ((source >= SlotStartAdd[SLOT_DWL_1 + i]) && + ((source + Length) <= (SlotStartAdd[SLOT_DWL_1 + i] + SLOT_SIZE(SLOT_DWL_1)))) + { + verified = 1U; + } + } + + if (verified == 0U) + { + return SE_ERROR; + } + + SE_DoubleECC_Error_Counter = 0U; + /* Do not use memcpy from lib : ECC error should be checked at each loop */ + for (i = 0; (i < Length) && (SE_DoubleECC_Error_Counter == 0U); i++, pDestination++, pSource++) + { + *pDestination = *pSource; + } + if (SE_DoubleECC_Error_Counter == 0U) + { + e_ret_status = SE_SUCCESS; + } + SE_DoubleECC_Error_Counter = 0U; + return e_ret_status; +} + +/** + * @} + */ + +/** @defgroup SE_HARDWARE_Exported_FLASH_EXT_Functions External FLASH Exported Functions + * @{ + */ + +/** + * @brief Initialization of external flash On The Fly DECryption (OTFDEC) + * @param pxSE_Metadata: Firmware metadata. + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_FLASH_EXT_Decrypt_Init(SE_FwRawHeaderTypeDef *pxSE_Metadata) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(pxSE_Metadata); + return SE_SUCCESS; +} + +/** + * @} + */ + +/** + * @brief Check if an array is inside the RAM of the product + * @param Addr : address of array + * @param Length : length of array in byte + */ +SE_ErrorStatus SE_LL_Buffer_in_ram(void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if ((Length != 0U) && (!((0xFFFFFFFFUL - addr_start) < Length)) + && ((addr_end <= SB_REGION_RAM_END) && (addr_start >= (SE_REGION_RAM_END + 1U)))) + { + e_ret_status = SE_SUCCESS; + } + else + { + e_ret_status = SE_ERROR; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + return e_ret_status; +} + +/** + * @brief function checking if a buffer is in sbsfu ram. + * @param pBuff: address of buffer + * @param Length: length of buffer in bytes + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_Buffer_in_SBSFU_ram(const void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if ((Length != 0U) && (!((0xFFFFFFFFUL - addr_start) < Length)) + && ((addr_end <= SB_REGION_RAM_END) && (addr_start >= SB_REGION_RAM_START))) + { + e_ret_status = SE_SUCCESS; + } + else + { + e_ret_status = SE_ERROR; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + return e_ret_status; +} + +/** + * @brief function checking if a buffer is PARTLY in se ram. + * @param pBuff: address of buffer + * @param Length: length of buffer in bytes + * @retval SE_ErrorStatus SE_SUCCESS for buffer in NOT se ram, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_Buffer_part_of_SE_ram(const void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if (((Length != 0U) && (!(((addr_start < SE_REGION_RAM_START) && (addr_end < SE_REGION_RAM_START)) || + ((addr_start > SE_REGION_RAM_END) && (addr_end > SE_REGION_RAM_END))))) + || ((0xFFFFFFFFUL - addr_start) < Length)) + { + e_ret_status = SE_SUCCESS; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + else + { + e_ret_status = SE_ERROR; + } + return e_ret_status; +} + +/** + * @brief function checking if a buffer is PARTLY in se rom. + * @param pBuff: address of buffer + * @param Length: length of buffer in bytes + * @retval SE_ErrorStatus SE_SUCCESS for buffer in NOT se rom, SE_ERROR otherwise. + */ +SE_ErrorStatus SE_LL_Buffer_part_of_SE_rom(const void *pBuff, uint32_t Length) +{ + SE_ErrorStatus e_ret_status; + uint32_t addr_start = (uint32_t)pBuff; + uint32_t addr_end = addr_start + Length - 1U; + + /* Check if length is positive with no overflow */ + if (((Length != 0U) && (!(((addr_start < SE_CODE_REGION_ROM_START) && (addr_end < SE_CODE_REGION_ROM_START)) + || ((addr_start > SE_CODE_REGION_ROM_END) && (addr_end > SE_CODE_REGION_ROM_END)) + ))) + || ((0xFFFFFFFFUL - addr_start) < Length)) + { + e_ret_status = SE_SUCCESS; + + /* Could be an attack ==> Reset */ + NVIC_SystemReset(); + } + else + { + e_ret_status = SE_ERROR; + } + return e_ret_status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SE_LOCK_KEYS_Exported_Functions + * @{ + */ + +/** + * @brief Lock the embedded keys used by SBSFU + * @param None + * @retval SE_ErrorStatus SE_SUCCESS if successful, SE_ERROR otherwise + */ +SE_ErrorStatus SE_LL_Lock_Keys(void) +{ +#ifdef KMS_ENABLED + uint32_t i_key_locked = 0U; + uint32_t i_ctrl = 0U; + +#ifdef KMS_INDEX_BLOBIMPORT_VERIFY + i_ctrl++; + if (KMS_LockKeyHandle(KMS_INDEX_BLOBIMPORT_VERIFY) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_INDEX_BLOBIMPORT_VERIFY */ +#ifdef KMS_INDEX_BLOBIMPORT_DECRYPT + i_ctrl++; + if (KMS_LockKeyHandle(KMS_INDEX_BLOBIMPORT_DECRYPT) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_INDEX_BLOBIMPORT_DECRYPT */ +#ifdef KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_1_AES128_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_2_AES128_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_3_AES128_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_1_ECDSA_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_2_ECDSA_OBJECT_HANDLE */ +#ifdef KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE + i_ctrl++; + if (KMS_LockKeyHandle(KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE) == CKR_OK) + { + i_key_locked++; + } +#endif /* KMS_SBSFU_KEY_3_ECDSA_OBJECT_HANDLE */ + if(i_ctrl == i_key_locked) + { + return SE_SUCCESS; + } + else + { + return SE_ERROR; + } +#else /* KMS_ENABLED */ + return SE_SUCCESS; +#endif /* KMS_ENABLED */ +} +/** + * @} + */ + +/** @addtogroup SE_HARDWARE_Private_Functions + * @{ + */ + +/** + * @brief Gets the page of a given address + * @param Addr: Address of the FLASH Memory + * @retval The page of a given address + */ +static uint32_t SE_LL_GetPage(uint32_t Address) +{ + uint32_t page; + + if (Address < (FLASH_BASE + (FLASH_BANK_SIZE))) + { + /* Bank 1 */ + page = (Address - FLASH_BASE) / FLASH_PAGE_SIZE; + } + else + { + /* Bank 2 */ + page = (Address - (FLASH_BASE + (FLASH_BANK_SIZE))) / FLASH_PAGE_SIZE; + } + return page; +} + +/** + * @brief Gets the bank of a given address + * @param Addr: Address of the FLASH Memory + * @retval The bank of a given address + */ + + +/** + * @brief Get Link Register value (LR) + * @param None. + * @retval LR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_LR(void) +{ + register uint32_t result; + +#if defined ( __ICCARM__ ) || ( __GNUC__ ) + __ASM volatile("MOV %0, LR" : "=r"(result)); +#elif defined ( __CC_ARM ) + __ASM volatile("MOV result, __return_address()"); +#endif /* ( __ICCARM__ ) || ( __GNUC__ ) */ + + return result; +} + +/* + As this handler code relies on stack pointer position to manipulate the PC return value, it is important + not to use extra registers (on top of scratch registers), because it would change the stack pointer + position. Then compiler optimizations are customized to ensure that. +*/ +#if defined(__ICCARM__) +#pragma optimize=none +#elif defined(__CC_ARM) +#pragma O0 +#elif defined(__ARMCC_VERSION) +__attribute__((optnone)) +#elif defined(__GNUC__) +__attribute__((optimize("O1"))) +#endif /* __ICCARM__ */ + +/** + * @brief NMI Handler present for handling Double ECC NMI interrupt + * @param None. + * @retval None. + */ +void NMI_Handler(void) +{ + uint32_t *p_sp; + uint32_t lr; + uint16_t opcode_msb; + + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)) + { + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); + + /* Memorize error to ignore the read value */ + SE_DoubleECC_Error_Counter++; + + lr = __get_LR(); + + /* Check EXC_RETURN value in LR to know which SP was used prior entering exception */ + if (((lr) & (0xFU)) == 0xDU) + { + /* interrupted code was using Process Stack Pointer */ + p_sp = (uint32_t *)__get_PSP(); + } + else + { + /* interrupted code was using Main Stack Pointer */ + p_sp = (uint32_t *)__get_MSP(); + } + + /* Test caller mode T bit from CPSR in stack */ + if ((*(p_sp + 7U) & (1U << xPSR_T_Pos)) != 0U) + { + /* Thumb mode. + Test PC in stack. + If bits [15:11] of the halfword being decoded take any of the following values, + the halfword is the first halfword of a 32-bit instruction: 0b11101, 0b11110, 0b11111. + Otherwise, the halfword is a 16-bit instruction. + */ + opcode_msb = (*(uint16_t *)(*(p_sp + 6) & 0xFFFFFFFEU) & 0xF800U); + if ((opcode_msb == 0xE800U) || (opcode_msb == 0xF000U) || (opcode_msb == 0xF800U)) + { + /* execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + else + { + /* execute next instruction PC +2 */ + *(p_sp + 6U) += 2U; + } + } + else + { + /* ARM mode execute next instruction PC +4 */ + *(p_sp + 6U) += 4U; + } + } + else + { + /* This exception occurs for another reason than flash double ECC errors */ + SE_NMI_ExceptionHandler(); + } +} + +/** + * @brief Hard Fault Handler present for handling Double ECC Bus Fault interrupt + * @param None. + * @retvat void + */ +void HardFault_Handler(void) +{ + SE_NMI_ExceptionHandler(); +} + +/** + * @brief Cleanup SE CORE + * The function is called during SE_LOCK_RESTRICT_SERVICES. + * + */ +void SE_LL_CORE_Cleanup(void) +{ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/readme.txt new file mode 100644 index 00000000..205abd15 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_SECoreBin/readme.txt @@ -0,0 +1,107 @@ +/** + @page 1_Image_SECoreBin / Secure Engine Core binary generation. + + @verbatim + ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* + * @file readme.txt + * @brief Secure Engine Core binary generation. + * SE Core binary exports SE CallGate function entry point for + * FU Application. + ****************************************************************************** + * + * Copyright (c) 2017 STMicroelectronics. All rights reserved. + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + @endverbatim + +@par Application Description + +This application is used to generate Secure Engine Core binary file to be linked +with Boot & Firmware Update application (BFU). +SE Core binary exports a single entry point to SE CallGate function and a startup method for data initialization. +It is based on the Secure Engine Middleware. + +Generated SE Core Binary embeds Key Management Services accessible through this same single entry point using APIs +defined by tKMS interface. + +It has to be compiled before BFU project. + +Three cryptographic schemes are provided as example to illustrate the cryptographic operations. The default +cryptographic scheme uses both symmetric (AES-CBC) and asymmetric (ECDSA) cryptography. Two alternate schemes are +provided and can be selected thanks to SECBOOT_CRYPTO_SCHEME compiler switch named : + - SECBOOT_ECCDSA_WITH_AES128_CBC_SHA256 (default) + - SECBOOT_ECCDSA_WITHOUT_ENCRYPT_SHA256 + - SECBOOT_AES128_GCM_AES128_GCM_AES128_GCM + +For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" +available from the STMicroelectronics microcontroller website www.st.com. + +@par Keywords + +Security, KMS, SBSFU + +@par Directory contents + + - 1_Image_SECoreBin/Src/ca_low_level.c Low level implementations of the Cryptographic API (CA) module + - 1_Image_SECoreBin/Src/kms_low_level.c Key Management Services low level interface + - 1_Image_SECoreBin/Src/nvms_low_level.c Non volatile memory storage low level interface + - 1_Image_SECoreBin/Src/se_low_level.c Low level interface + - 1_Image_SECoreBin/Inc/ca_conf.h Configuration for Cryptographic API (CA) module functionalities + - 1_Image_SECoreBin/Inc/ca_low_level.h Header for ca_low_level.c + - 1_Image_SECoreBin/Inc/kms_config.h Key Management Services configuration file + - 1_Image_SECoreBin/Inc/kms_low_level.h Header for kms_low_level.c + - 1_Image_SECoreBin/Inc/kms_mem_pool_def.h KMS memory pool definition file + - 1_Image_SECoreBin/Inc/kms_platf_objects_config.h.pattern Header for Key Management Services embedded objects definitions pattern + Appropriate cryptographic scheme keys are injected into it by the prebuild script (see below) + - 1_Image_SECoreBin/Inc/kms_platf_objects_interface.h Header for Key Management Services embedded objects references (labels, IDs...) + Exported to KMS user to ease embedded object usage + - 1_Image_SECoreBin/Inc/mbed_crypto_config.h mbed-crypto configuration file + - 1_Image_SECoreBin/Inc/nvms_low_level.h Header for nvms_low_level.c + - 1_Image_SECoreBin/Inc/se_crypto_config.h Crypto scheme configuration (crypto scheme used by the bootloader) + - 1_Image_SECoreBin/Inc/se_def_metadata.h Firmware metadata (header) definition + - 1_Image_SECoreBin/Inc/se_low_level.h Header file for low level interface + - 1_Image_SECoreBin/Inc/stm32wlxx_hal_conf.h HAL configuration file + - 1_Image_SECoreBin/Binary/ECCKEY1.txt Private ECCDSA key for signature verification + - 1_Image_SECoreBin/Binary/nonce.bin Number used only once for firmware encryption + - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_CBC.bin Public key for AES CBC encryption + - 1_Image_SECoreBin/Binary/OEM_KEY_COMPANY1_key_AES_GCM.bin Public key for AES GCM encryption + +@par Hardware and Software environment + + - This example runs on STM32WL55xx devices + - This example has been tested with NUCLEO-WL55JC RevC board and can be easily tailored to any other supported device and + development board. + - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware is a feature provided by + STM32Cube programmer available on www.st.com. + - Microsoft Windows has a limitation whereby paths to files and directories cannot be longer than 256 characters. + Paths to files exceeding that limits cause tools (e.g. compilers, shell scripts) to fail reading from or writing + to such files. As a workaround, it is advised to use the subst.exe command from within a command prompt to set up + a local drive out of an existing directory on the hard drive, such as: + C:\> subst X: \Firmware + + +@par IDE prebuild script + +In order to ease the development process, a prebuild script ("prebuild.bat") is integrated in each IDE project. +This preliminary processing is in charge of: + - determining the requested cryptographic scheme + - generating the appropriate keys in /kms_platf_objects_config.h (from injection of BFU & Blob importation + keys into the KMS embedded objects pattern file) + - generating the appropriate script to prepare the firmware image ("postbuild.bat") when building the UserApp project + +A known limitation of this integration occurs when you update a cryptographic parameter (for instance the cryptographic +key). The IDE does not track this update so you need to force the rebuild of the project manually. + +@par How to use it ? + +In order to generate Secure Engine Core binary file, you must do the following : + - Open your preferred toolchain + - Rebuild the project + + *

      © COPYRIGHT STMicroelectronics

      + */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.ewd b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.ewd new file mode 100644 index 00000000..b17c2229 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.ewd @@ -0,0 +1,1419 @@ + + + 3 + + STM32WL55JC_Nucleo_1_Image_UserApp + + ARM + + 1 + + C-SPY + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.ewp b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.ewp new file mode 100644 index 00000000..53fe7196 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.ewp @@ -0,0 +1,1198 @@ + + + 2 + + STM32WL55JC_Nucleo_1_Image_UserApp + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + cmd /C "cmd /C $PROJ_DIR$\..\..\1_Image_SECoreBin\EWARM\postbuild.bat "$PROJ_DIR$" "$TARGET_PATH$" "$PROJ_DIR$\UserApp.bin" 1 1" + + + + ILINK + 0 + + 21 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Doc + + $PROJ_DIR$\..\readme.txt + + + + Application + + User + + $PROJ_DIR$\..\Src\main.c + + + $PROJ_DIR$\..\Src\com.c + + + $PROJ_DIR$\..\Src\common.c + + + $PROJ_DIR$\..\Src\fw_update_app.c + + + $PROJ_DIR$\..\Src\se_user_code.c + + + $PROJ_DIR$\..\Src\test_protections.c + + + $PROJ_DIR$\..\Src\ymodem.c + + + $PROJ_DIR$\..\Src\flash_if.c + + + $PROJ_DIR$\..\Src\stm32wlxx_it.c + + + $PROJ_DIR$\..\Src\kms_object_update_app.c + + + $PROJ_DIR$\..\Src\tkms_app.c + + + $PROJ_DIR$\..\Src\tkms_app_derive_key.c + + + $PROJ_DIR$\..\Src\tkms_app_encrypt_decrypt.c + + + $PROJ_DIR$\..\Src\tkms_app_find.c + + + $PROJ_DIR$\..\Src\tkms_app_sign_verify.c + + + + SFU_Services + + $PROJ_DIR$\..\Src\sfu_app_new_image.c + + + + EWARM + + $PROJ_DIR$\startup_stm32wl55xx_cm4.s + + + + + Drivers + + BSP + + STM32WLxx_Nucleo + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\BSP\STM32WLxx_Nucleo\stm32wlxx_nucleo.c + + + + + STM32WLxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_cortex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_crc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_iwdg.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_pwr_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rcc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_rtc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_uart_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_exti.c + + + $PROJ_DIR$\..\..\..\..\..\..\Drivers\STM32WLxx_HAL_Driver\Src\stm32wlxx_hal_flash.c + + + + CMSIS + + $PROJ_DIR$\..\Src\system_stm32wlxx.c + + + + + Middlewares + + STM32_Secure_Engine + + $PROJ_DIR$\..\..\1_Image_BFU\EWARM\se_interface_appli.o + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/EWARM/Project.eww b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.eww similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/EWARM/Project.eww rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/Project.eww diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s new file mode 100644 index 00000000..658ca8e5 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/startup_stm32wl55xx_cm4.s @@ -0,0 +1,509 @@ +;******************************************************************************** +;* File Name : startup_stm32wl55xx_cm4.s +;* Author : MCD Application Team +;* Description : M4 core vector table of the STM32WLxxxx devices for the +;* IAR (EWARM) toolchain. +;* +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* +;* Copyright (c) 2020(2021) STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +; +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD and PVM Interrupt + DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSRU Interrupts + DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt + DCD FLASH_IRQHandler ; FLASH global Interrupt + DCD RCC_IRQHandler ; RCC Interrupt + DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt + DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt + DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt + DCD EXTI3_IRQHandler ; EXTI Line 3 Interrupt + DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt + DCD ADC_IRQHandler ; ADC Interrupt + DCD DAC_IRQHandler ; DAC Interrupt + DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV Interrupt + DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts + DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt + DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt + DCD TIM2_IRQHandler ; TIM2 Global Interrupt + DCD TIM16_IRQHandler ; TIM16 Global Interrupt + DCD TIM17_IRQHandler ; TIM17 Global Interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt + DCD SPI1_IRQHandler ; SPI1 Interrupt + DCD SPI2_IRQHandler ; SPI2 Interrupt + DCD USART1_IRQHandler ; USART1 Interrupt + DCD USART2_IRQHandler ; USART2 Interrupt + DCD LPUART1_IRQHandler ; LPUART1 Interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 Global Interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 Global Interrupt + DCD EXTI15_10_IRQHandler ; EXTI Lines [15:10] Interrupt + DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 Global Interrupt + DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt + DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt + DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt + DCD HSEM_IRQHandler ; HSEM0 Interrupt + DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt + DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt + DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt + DCD AES_IRQHandler ; AES Interrupt + DCD RNG_IRQHandler ; RNG1 Interrupt + DCD PKA_IRQHandler ; PKA Interrupt + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt + DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_PVM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_PVM_IRQHandler + B PVD_PVM_IRQHandler + + PUBWEAK TAMP_STAMP_LSECSS_SSRU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_STAMP_LSECSS_SSRU_IRQHandler + B TAMP_STAMP_LSECSS_SSRU_IRQHandler + + PUBWEAK RTC_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_WKUP_IRQHandler + B RTC_WKUP_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel2_IRQHandler + B DMA1_Channel2_IRQHandler + + PUBWEAK DMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel3_IRQHandler + B DMA1_Channel3_IRQHandler + + PUBWEAK DMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel4_IRQHandler + B DMA1_Channel4_IRQHandler + + PUBWEAK DMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel5_IRQHandler + B DMA1_Channel5_IRQHandler + + PUBWEAK DMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel6_IRQHandler + B DMA1_Channel6_IRQHandler + + PUBWEAK DMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel7_IRQHandler + B DMA1_Channel7_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK DAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC_IRQHandler + B DAC_IRQHandler + + PUBWEAK C2SEV_PWR_C2H_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +C2SEV_PWR_C2H_IRQHandler + B C2SEV_PWR_C2H_IRQHandler + + PUBWEAK COMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP_IRQHandler + B COMP_IRQHandler + + PUBWEAK EXTI9_5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_5_IRQHandler + B EXTI9_5_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK EXTI15_10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_10_IRQHandler + B EXTI15_10_IRQHandler + + PUBWEAK RTC_Alarm_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Alarm_IRQHandler + B RTC_Alarm_IRQHandler + + PUBWEAK LPTIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM3_IRQHandler + B LPTIM3_IRQHandler + + PUBWEAK SUBGHZSPI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZSPI_IRQHandler + B SUBGHZSPI_IRQHandler + + PUBWEAK IPCC_C1_RX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_RX_IRQHandler + B IPCC_C1_RX_IRQHandler + + PUBWEAK IPCC_C1_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPCC_C1_TX_IRQHandler + B IPCC_C1_TX_IRQHandler + + PUBWEAK HSEM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HSEM_IRQHandler + B HSEM_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK SUBGHZ_Radio_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUBGHZ_Radio_IRQHandler + B SUBGHZ_Radio_IRQHandler + + PUBWEAK AES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AES_IRQHandler + B AES_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK PKA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PKA_IRQHandler + B PKA_IRQHandler + + PUBWEAK DMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel1_IRQHandler + B DMA2_Channel1_IRQHandler + + PUBWEAK DMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel2_IRQHandler + B DMA2_Channel2_IRQHandler + + PUBWEAK DMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel3_IRQHandler + B DMA2_Channel3_IRQHandler + + PUBWEAK DMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel4_IRQHandler + B DMA2_Channel4_IRQHandler + + PUBWEAK DMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel5_IRQHandler + B DMA2_Channel5_IRQHandler + + PUBWEAK DMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel6_IRQHandler + B DMA2_Channel6_IRQHandler + + PUBWEAK DMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2_Channel7_IRQHandler + B DMA2_Channel7_IRQHandler + + PUBWEAK DMAMUX1_OVR_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMAMUX1_OVR_IRQHandler + B DMAMUX1_OVR_IRQHandler + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf new file mode 100644 index 00000000..ae672ac8 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/EWARM/stm32wl55xx_flash_cm4.icf @@ -0,0 +1,43 @@ +/*###ICF### Set of symbols used in UserApp project ****/ + +define memory mem with size = 4G; + +/******************************************************************************/ +/* Include of SBSFU symbols file */ +/* (Project>Options>Linker>Extra Options --config_search option is used to */ +/* specify the the directory to search for include files */ +/******************************************************************************/ +include "mapping_sbsfu.icf"; +include "mapping_fwimg.icf"; + +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = __ICFEDIT_SLOT_Active_1_start__ + 512; +define symbol __ICFEDIT_region_ROM_end__ = __ICFEDIT_SLOT_Active_1_end__ ; +define symbol __ICFEDIT_region_RAM_start__ = __ICFEDIT_SE_region_RAM_end__ + 1; +define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x200; + +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +/* to make sure the binary size is a multiple of the AES block size (16 bytes) and WL flash writing unit (8 bytes) */ +define root section aes_block_padding with alignment=16 +{ +udata8 "Force Alignment"; +pad_to 16; +}; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_region_ROM_start__ { readonly section .intvec }; + +place in ROM_region { readonly, last section aes_block_padding }; +place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/com.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/com.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/com.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/com.h diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/common.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/common.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/common.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/common.h diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/flash_if.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/flash_if.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/flash_if.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/flash_if.h diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/fw_update_app.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/fw_update_app.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/fw_update_app.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/fw_update_app.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/main.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/main.h new file mode 100644 index 00000000..2b6c9321 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/main.h @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * @file main.h + * @author MCD Application Team + * @brief This file contains definitions for main application file. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MAIN_H +#define MAIN_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wlxx_hal.h" +#include "stm32wlxx_nucleo.h" +#include "com.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* User can use this section to tailor UARTx instance used and associated + resources */ + +#define BUTTON_INIT() BSP_PB_Init(BUTTON_SW1,BUTTON_MODE_GPIO); +#define BUTTON_PUSHED() (BSP_PB_GetState(BUTTON_SW1) == GPIO_PIN_RESET) +#define BUTTON_INIT_EXTI() BSP_PB_Init(BUTTON_SW1, BUTTON_MODE_EXTI) +#define BUTTON_IRQHANDLER EXTI0_IRQHandler +#define BUTTON_EXTI_LINE BUTTON_SW1_PIN + +/* Definition for USARTx clock resources */ +#define SFU_UART USART2 +#define SFU_UART_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() +#define SFU_UART_CLK_DISABLE() __HAL_RCC_USART2_CLK_DISABLE() + +#define SFU_UART_TX_AF GPIO_AF7_USART2 +#define SFU_UART_TX_GPIO_PORT GPIOA +#define SFU_UART_TX_PIN GPIO_PIN_2 +#define SFU_UART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_UART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() + +#define SFU_UART_RX_AF GPIO_AF7_USART2 +#define SFU_UART_RX_GPIO_PORT GPIOA +#define SFU_UART_RX_PIN GPIO_PIN_3 +#define SFU_UART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define SFU_UART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() + +/* Maximum Timeout values for flags waiting loops. + You may modify these timeout values depending on CPU frequency and application + conditions (interrupts routines ...). */ +#define SFU_UART_TIMEOUT_MAX 1000U + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* MAIN_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/se_user_code.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/se_user_code.h new file mode 100644 index 00000000..259569d7 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/se_user_code.h @@ -0,0 +1,65 @@ +/** + ****************************************************************************** + * @file se_user_code.h + * @author MCD Application Team + * @brief Secure Engine User code example module. + * This file demonstrates how to call user defined services running + * in Secure Engine. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SE_USER_CODE_H +#define SE_USER_CODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup SE_USER_CODE Secure Engine User Code Example + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ + +/** @addtogroup SE_USER_CODE_Exported_Functions + * @{ + */ + +void SE_USER_CODE_RunMenu(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SE_USER_CODE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/sfu_app_new_image.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/sfu_app_new_image.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/sfu_app_new_image.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/sfu_app_new_image.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_hal_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_hal_conf.h new file mode 100644 index 00000000..e1d0d6af --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_hal_conf.h @@ -0,0 +1,340 @@ +/** + ****************************************************************************** + * @file stm32wlxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLxx_HAL_CONF_H +#define STM32WLxx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_COMP_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_GTZC_MODULE_ENABLED */ +/* #define HAL_HSEM_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IPCC_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +#define HAL_IWDG_MODULE_ENABLED +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_PKA_MODULE_ENABLED */ +/* #define HAL_RNG_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPI_MODULE_ENABLED */ +/* #define HAL_SUBGHZ_MODULE_ENABLED */ +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_EXTI_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED + +/* ########################## Register Callbacks selection ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0u +#define USE_HAL_COMP_REGISTER_CALLBACKS 0u +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u +#define USE_HAL_DAC_REGISTER_CALLBACKS 0u +#define USE_HAL_I2C_REGISTER_CALLBACKS 0u +#define USE_HAL_I2S_REGISTER_CALLBACKS 0u +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u +#define USE_HAL_PKA_REGISTER_CALLBACKS 0u +#define USE_HAL_RNG_REGISTER_CALLBACKS 0u +#define USE_HAL_RTC_REGISTER_CALLBACKS 0u +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u +#define USE_HAL_SPI_REGISTER_CALLBACKS 0u +#define USE_HAL_SUBGHZ_REGISTER_CALLBACKS 0u +#define USE_HAL_TIM_REGISTER_CALLBACKS 0u +#define USE_HAL_UART_REGISTER_CALLBACKS 0u +#define USE_HAL_USART_REGISTER_CALLBACKS 0u +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ + +#if !defined (HSE_VALUE) +#define HSE_VALUE 32000000UL /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) +#define MSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @brief Internal Multiple Speed oscillator (HSI48) default value. + * This value is the default HSI48 range value after Reset. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE 48000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI48_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((1uL <<__NVIC_PRIO_BITS) - 1uL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 1U + +/* ################## CRYP peripheral configuration ########################## */ + +#define USE_HAL_CRYP_SUSPEND_RESUME 1U + + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32wlxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32wlxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32wlxx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32wlxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32wlxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32wlxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32wlxx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32wlxx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32wlxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32wlxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED + #include "stm32wlxx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED + #include "stm32wlxx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32wlxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32wlxx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IPCC_MODULE_ENABLED + #include "stm32wlxx_hal_ipcc.h" +#endif /* HAL_IPCC_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32wlxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32wlxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32wlxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32wlxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32wlxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32wlxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32wlxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32wlxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32wlxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32wlxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32wlxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SUBGHZ_MODULE_ENABLED + #include "stm32wlxx_hal_subghz.h" +#endif /* HAL_SUBGHZ_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32wlxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32wlxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32wlxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32wlxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLxx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_it.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_it.h new file mode 100644 index 00000000..b2e599ac --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_it.h @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * @file stm32wlxx_it.h + * @author MCD Application Team + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLxx_IT_H +#define STM32WLxx_IT_H + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup USER_APP_COMMON Common + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void FLASH_IRQHandler(void); +void TAMP_STAMP_LSECSS_SSRU_IRQHandler(void); +void BUTTON_IRQHANDLER(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLxx_IT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h new file mode 100644 index 00000000..0af7b23e --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * @file stm32wlxx_nucleo_conf.h + * @author MCD Application Team + * @brief STM32WLxx_Nucleo board configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2020(-2021) STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WLXX_NUCLEO_CONF_H +#define STM32WLXX_NUCLEO_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wlxx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WLXX_NUCLEO + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG CONFIG + * @{ + */ + +/** @defgroup STM32WLXX_NUCLEO_CONFIG_Exported_Constants Exported Constants + * @{ + */ +/* COM usage define */ +#define USE_BSP_COM_FEATURE 0U + +/* COM log define */ +#define USE_COM_LOG 0U + +/* IRQ priorities */ +#define BSP_BUTTON_SWx_IT_PRIORITY 15U + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WLXX_NUCLEO_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/test_protections.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/test_protections.h new file mode 100644 index 00000000..1fa6819f --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/test_protections.h @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file test_protections.h + * @author MCD Application Team + * @brief This file contains definitions for Test Protections functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef TEST_PROTECTIONS_H +#define TEST_PROTECTIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stdint.h" + +/* Exported constants --------------------------------------------------------*/ +/* Tamper instance used by SBSFU */ +#define RTC_TAMPER_ID RTC_TAMPER_1 + +/* Exported macros -----------------------------------------------------------*/ +/* SFU Redirect of RTC Tamper Event Callback*/ +#define CALLBACK_Antitamper(void) HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc) + +/* Exported functions ------------------------------------------------------- */ +void TEST_PROTECTIONS_RunMenu(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TEST_PROTECTIONS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/tkms_app.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/tkms_app.h new file mode 100644 index 00000000..da212f0b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/tkms_app.h @@ -0,0 +1,63 @@ +/** + ****************************************************************************** + * @file tkms_app.h + * @author MCD Application Team + * @brief This file contains definitions for tkms application examples. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef KMS_APP_H +#define KMS_APP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "app_sfu.h" + +/* Exported macros -----------------------------------------------------------*/ +#if defined(SFU_IWDG_PROTECT_ENABLE) +/* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload register */ +#define INVOKE_SCHEDULE_NEEDS() \ + do { \ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); \ + } while(0); +#else +#define INVOKE_SCHEDULE_NEEDS() \ + do { \ + ; \ + } while(0); +#endif /* SFU_IWDG_PROTECT_ENABLE */ + + + +/* Exported functions ------------------------------------------------------- */ +void tkms_app_menu(void); +void tkms_buff2str(uint8_t *pbuff, uint8_t *pstr, uint32_t length); + +CK_RV tkms_app_encrypt_decrypt_aes_gcm(uint32_t length, uint8_t *pClearMessage); +CK_RV tkms_app_encrypt_decrypt_aes_cbc(uint32_t length, uint8_t *pClearMessage); +CK_RV tkms_app_sign_verify_rsa(uint32_t length, uint8_t *pMessage); +CK_RV tkms_app_derive_key(uint32_t length, uint8_t *pMessage); +CK_RV tkms_app_find(void); + +#ifdef __cplusplus +} +#endif + +#endif /* KMS_APP_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/ymodem.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/ymodem.h similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Inc/ymodem.h rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Inc/ymodem.h diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/Project.uvoptx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/Project.uvoptx new file mode 100644 index 00000000..e39030e8 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/Project.uvoptx @@ -0,0 +1,771 @@ + + + + 1.0 + +
      ### uVision Project, (C) Keil Software
      + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32WL55JC_Nucleo_1_Image_UserApp + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + STM32WL55JC_Nucleo/List\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + .\STM32WL_CM4.ini + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32WLxx_CM4 -FL040000 -FS08000000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=98,207,509,709,0)(1007=673,180,880,401,0)(1008=566,409,942,645,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + + + + 1 + 2 + 0x2000A400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + System Viewer\DBGMCU + 35904 + + + System Viewer\NVIC + 35901 + + + System Viewer\SCB + 35905 + + + System Viewer\SYSCFG + 35903 + + + System Viewer\SYSCFG_continue + 35902 + + + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + .\startup_stm32wl55xx_cm4.s + startup_stm32wl55xx_cm4.s + 0 + 0 + + + + + Application/User + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ../Src/com.c + com.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ../Src/common.c + common.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ../Src/flash_if.c + flash_if.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ../Src/fw_update_app.c + fw_update_app.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ../Src/kms_object_update_app.c + kms_object_update_app.c + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ../Src/main.c + main.c + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ../Src/se_user_code.c + se_user_code.c + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ../Src/sfu_app_new_image.c + sfu_app_new_image.c + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ../Src/stm32wlxx_it.c + stm32wlxx_it.c + 0 + 0 + + + 2 + 11 + 1 + 0 + 0 + 0 + ../Src/test_protections.c + test_protections.c + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ../Src/tkms_app.c + tkms_app.c + 0 + 0 + + + 2 + 13 + 1 + 0 + 0 + 0 + ../Src/tkms_app_derive_key.c + tkms_app_derive_key.c + 0 + 0 + + + 2 + 14 + 1 + 0 + 0 + 0 + ../Src/tkms_app_encrypt_decrypt.c + tkms_app_encrypt_decrypt.c + 0 + 0 + + + 2 + 15 + 1 + 0 + 0 + 0 + ../Src/tkms_app_find.c + tkms_app_find.c + 0 + 0 + + + 2 + 16 + 1 + 0 + 0 + 0 + ../Src/tkms_app_sign_verify.c + tkms_app_sign_verify.c + 0 + 0 + + + 2 + 17 + 1 + 0 + 0 + 0 + ../Src/ymodem.c + ymodem.c + 0 + 0 + + + + + Doc + 1 + 0 + 0 + 0 + + 3 + 18 + 5 + 0 + 0 + 0 + ../readme.txt + readme.txt + 0 + 0 + + + + + Drivers/BSP/STM32WLxx_Nucleo + 0 + 0 + 0 + 0 + + 4 + 19 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + stm32wlxx_nucleo.c + 0 + 0 + + + + + Drivers/STM32WLxx_HAL_Driver + 0 + 0 + 0 + 0 + + 5 + 20 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + stm32wlxx_hal.c + 0 + 0 + + + 5 + 21 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + stm32wlxx_hal_cortex.c + 0 + 0 + + + 5 + 22 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + stm32wlxx_hal_crc.c + 0 + 0 + + + 5 + 23 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + stm32wlxx_hal_crc_ex.c + 0 + 0 + + + 5 + 24 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + stm32wlxx_hal_dma.c + 0 + 0 + + + 5 + 25 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c + stm32wlxx_hal_dma_ex.c + 0 + 0 + + + 5 + 26 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + stm32wlxx_hal_exti.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + stm32wlxx_hal_flash.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + stm32wlxx_hal_flash_ex.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + stm32wlxx_hal_gpio.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + stm32wlxx_hal_iwdg.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + stm32wlxx_hal_pwr.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + stm32wlxx_hal_pwr_ex.c + 0 + 0 + + + 5 + 33 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + stm32wlxx_hal_rcc.c + 0 + 0 + + + 5 + 34 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + stm32wlxx_hal_rcc_ex.c + 0 + 0 + + + 5 + 35 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + stm32wlxx_hal_rtc.c + 0 + 0 + + + 5 + 36 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + stm32wlxx_hal_rtc_ex.c + 0 + 0 + + + 5 + 37 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + stm32wlxx_hal_uart.c + 0 + 0 + + + 5 + 38 + 1 + 0 + 0 + 0 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + stm32wlxx_hal_uart_ex.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 6 + 39 + 1 + 0 + 0 + 0 + ../Src/system_stm32wlxx.c + system_stm32wlxx.c + 0 + 0 + + + + + Middlewares/STM32_Secure_Engine + 0 + 0 + 0 + 0 + + 7 + 40 + 3 + 0 + 0 + 0 + ..\..\1_Image_BFU\MDK-ARM\STM32WL55JC_Nucleo\Exe\se_interface_appli.txt + se_interface_appli.txt + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/Project.uvprojx b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/Project.uvprojx new file mode 100644 index 00000000..1e679dd1 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/Project.uvprojx @@ -0,0 +1,637 @@ + + + + 2.1 + +
      ### uVision Project, (C) Keil Software
      + + + + STM32WL55JC_Nucleo_1_Image_UserApp + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + STM32WL55JCIx:CM4 + STMicroelectronics + Keil.STM32WLxx_DFP.1.1.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x10000) IROM(0x08000000,0x40000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32WLxx_CM4 -FS08000000 -FL040000 -FP0($$Device:STM32WL55JCIx$CMSIS\Flash\STM32WLxx_CM4.FLM)) + 0 + $$Device:STM32WL55JCIx$Drivers\CMSIS\Device\ST\STM32WLxx\Include\stm32wlxx.h + + + + + + + + + + $$Device:STM32WL55JCIx$CMSIS\SVD\STM32WL5x_CM4.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\STM32WL55JC_Nucleo\Exe\ + UserApp + 1 + 0 + 0 + 1 + 1 + STM32WL55JC_Nucleo/List\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 1 + fromelf #L --bincombined --output=$L../../@L.bin + .\..\..\1_Image_SECoreBin\MDK-ARM\postbuild.bat . #L @L.bin 1 1 + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 5 + 3 + 0 + 0 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32WL55xx,CORE_CM4,KMS_ENABLED,DISABLE_IMAGE_STATE_HANDLING + + ../Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc;../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy;../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include;../../../../../../Drivers/CMSIS/Include;../../../../../../Drivers/BSP/STM32WLxx_Nucleo;../../../../../../Middlewares/ST/STM32_Secure_Engine/Core;../../1_Image_SECoreBin/Inc;../../1_Image_BFU/BFU/App;../../Linker_Common/MDK-ARM;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Core;../../../../../../Middlewares/ST/STM32_Key_Management_Services/iKMS;../../../../../../Middlewares/ST/STM32_Key_Management_Services/Interface;../../../../../../Drivers/BSP/STM32WLxx_Nucleo + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + .\UserApp.sct + + + + + + + + + + + Application/MDK-ARM + + + startup_stm32wl55xx_cm4.s + 2 + .\startup_stm32wl55xx_cm4.s + + + + + Application/User + + + com.c + 1 + ../Src/com.c + + + common.c + 1 + ../Src/common.c + + + flash_if.c + 1 + ../Src/flash_if.c + + + fw_update_app.c + 1 + ../Src/fw_update_app.c + + + kms_object_update_app.c + 1 + ../Src/kms_object_update_app.c + + + main.c + 1 + ../Src/main.c + + + se_user_code.c + 1 + ../Src/se_user_code.c + + + sfu_app_new_image.c + 1 + ../Src/sfu_app_new_image.c + + + stm32wlxx_it.c + 1 + ../Src/stm32wlxx_it.c + + + test_protections.c + 1 + ../Src/test_protections.c + + + tkms_app.c + 1 + ../Src/tkms_app.c + + + tkms_app_derive_key.c + 1 + ../Src/tkms_app_derive_key.c + + + tkms_app_encrypt_decrypt.c + 1 + ../Src/tkms_app_encrypt_decrypt.c + + + tkms_app_find.c + 1 + ../Src/tkms_app_find.c + + + tkms_app_sign_verify.c + 1 + ../Src/tkms_app_sign_verify.c + + + ymodem.c + 1 + ../Src/ymodem.c + + + + + Doc + + + readme.txt + 5 + ../readme.txt + + + + + Drivers/BSP/STM32WLxx_Nucleo + + + stm32wlxx_nucleo.c + 1 + ../../../../../../Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + + + Drivers/STM32WLxx_HAL_Driver + + + stm32wlxx_hal.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + stm32wlxx_hal_cortex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + stm32wlxx_hal_crc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + stm32wlxx_hal_crc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + stm32wlxx_hal_dma.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + + + stm32wlxx_hal_dma_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c + + + stm32wlxx_hal_exti.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + stm32wlxx_hal_flash.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + stm32wlxx_hal_flash_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + stm32wlxx_hal_gpio.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + stm32wlxx_hal_iwdg.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + stm32wlxx_hal_pwr.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + stm32wlxx_hal_pwr_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + stm32wlxx_hal_rcc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + stm32wlxx_hal_rcc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + stm32wlxx_hal_rtc.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + stm32wlxx_hal_rtc_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + stm32wlxx_hal_uart.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + stm32wlxx_hal_uart_ex.c + 1 + ../../../../../../Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + + + Drivers/CMSIS + + + system_stm32wlxx.c + 1 + ../Src/system_stm32wlxx.c + + + + + Middlewares/STM32_Secure_Engine + + + se_interface_appli.txt + 3 + ..\..\1_Image_BFU\MDK-ARM\STM32WL55JC_Nucleo\Exe\se_interface_appli.txt + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
      diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/UserApp.sct b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/UserApp.sct new file mode 100644 index 00000000..e0efa2a0 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/UserApp.sct @@ -0,0 +1,29 @@ +#! armclang --target=arm-arm-none-eabi -mcpu=cortex-m0plus -E -xc +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* +#include "..\..\Linker_Common\MDK-ARM\mapping_sbsfu.h" +#include "..\..\Linker_Common\MDK-ARM\mapping_fwimg.h" + +LR_ROM (SLOT_ACTIVE_1_START + 0x200) { ; 0x200 = IMAGE_OFFSET + vector_start (SLOT_ACTIVE_1_START + 0x200) FIXED VECTOR_SIZE { + *.o (RESET, +First) + } + ROM_region +0 { + *(InRoot$$Sections) + .ANY (+RO) + } +; SBSFU RAM area is reused for UserApp + RAM_region SB_REGION_RAM_START SB_RAM_REGION_SIZE { + .ANY (STACK) + .ANY (HEAP) + .ANY (+RW +ZI) + } +} + +; extra ROM region to make sure the binary size is a multiple of the AES block size (16 bytes) and WL flash writing unit (8 bytes) +LR_ROM1(+0) ALIGN(16) { + ForAlignment +0 { + startup_stm32wl55xx_cm4.o (ALIGNTOAESBLOCK,+Last) + } +} diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/startup_stm32wl55xx_cm4.s b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/startup_stm32wl55xx_cm4.s new file mode 100644 index 00000000..fba95749 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/MDK-ARM/startup_stm32wl55xx_cm4.s @@ -0,0 +1,371 @@ +;****************************************************************************** +;* File Name : startup_stm32wl55xx_cm4.s +;* Author : MCD Application Team +;* Description : STM32WL55xx devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the CortexM4 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;* <<< Use Configuration Wizard in Context Menu >>> +;****************************************************************************** +;* @attention +;* +;* Copyright (c) 2020 STMicroelectronics. All rights reserved. +;* +;* This software component is licensed by ST under 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: +;* opensource.org/licenses/Apache-2.0 +;* +;****************************************************************************** + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000800 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_PVM_IRQHandler ; PVD and PVM detector + DCD TAMP_STAMP_LSECSS_SSRU_IRQHandler ; RTC Tamper, RTC TimeStamp, LSECSS and RTC SSR Underflow Interrupts + DCD RTC_WKUP_IRQHandler ; RTC Wakeup Interrupt + DCD FLASH_IRQHandler ; FLASH global Interrupt + DCD RCC_IRQHandler ; RCC Interrupt + DCD EXTI0_IRQHandler ; EXTI Line 0 Interrupt + DCD EXTI1_IRQHandler ; EXTI Line 1 Interrupt + DCD EXTI2_IRQHandler ; EXTI Line 2 Interrupt + DCD EXTI3_IRQHandler ; EXTI Line 3 Interrup + DCD EXTI4_IRQHandler ; EXTI Line 4 Interrupt + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 Interrupt + DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 Interrupt + DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 Interrupt + DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 Interrupt + DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 Interrupt + DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 Interrupt + DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 Interrupt + DCD ADC_IRQHandler ; ADC Interrupt + DCD DAC_IRQHandler ; DAC Interrupt + DCD C2SEV_PWR_C2H_IRQHandler ; CPU M0+ SEV and PWR CPU M0+ HOLD wakeup Interrupt + DCD COMP_IRQHandler ; COMP1 and COMP2 Interrupts + DCD EXTI9_5_IRQHandler ; EXTI Lines [9:5] Interrupt + DCD TIM1_BRK_IRQHandler ; TIM1 Break Interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update Interrupts + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Communication Interrupts + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare Interrupt + DCD TIM2_IRQHandler ; TIM2 Global Interrupt + DCD TIM16_IRQHandler ; TIM16 Global Interrupt + DCD TIM17_IRQHandler ; TIM17 Global Interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event Interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error Interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event Interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error Interrupt + DCD SPI1_IRQHandler ; SPI1 Interrupt + DCD SPI2_IRQHandler ; SPI2 Interrupt + DCD USART1_IRQHandler ; USART1 Interrupt + DCD USART2_IRQHandler ; USART2 Interrupt + DCD LPUART1_IRQHandler ; LPUART1 Interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 Interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 Interrupt + DCD EXTI15_10_IRQHandler ; EXTI Lines1[15:10 ]Interrupts + DCD RTC_Alarm_IRQHandler ; RTC Alarms (A and B) Interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 Interrupt + DCD SUBGHZSPI_IRQHandler ; SUBGHZSPI Interrupt + DCD IPCC_C1_RX_IRQHandler ; IPCC CPU1 RX occupied interrupt + DCD IPCC_C1_TX_IRQHandler ; IPCC CPU1 RX free interrupt + DCD HSEM_IRQHandler ; HSEM0 Interrupt + DCD I2C3_EV_IRQHandler ; I2C3 Event Interrupt + DCD I2C3_ER_IRQHandler ; I2C3 Error Interrupt + DCD SUBGHZ_Radio_IRQHandler ; SUBGHZ Radio Interrupt + DCD AES_IRQHandler ; AES Interrupt + DCD RNG_IRQHandler ; RNG1 Interrupt + DCD PKA_IRQHandler ; PKA Interrupt + DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 Interrupt + DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 Interrupt + DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 Interrupt + DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 Interrupt + DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 Interrupt + DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 Interrupt + DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 Interrupt + DCD DMAMUX1_OVR_IRQHandler ; DMAMUX overrun Interrupt + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_PVM_IRQHandler [WEAK] + EXPORT TAMP_STAMP_LSECSS_SSRU_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT DAC_IRQHandler [WEAK] + EXPORT C2SEV_PWR_C2H_IRQHandler [WEAK] + EXPORT COMP_IRQHandler [WEAK] + EXPORT EXTI9_5_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT EXTI15_10_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT LPTIM3_IRQHandler [WEAK] + EXPORT SUBGHZSPI_IRQHandler [WEAK] + EXPORT IPCC_C1_RX_IRQHandler [WEAK] + EXPORT IPCC_C1_TX_IRQHandler [WEAK] + EXPORT HSEM_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SUBGHZ_Radio_IRQHandler [WEAK] + EXPORT AES_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT PKA_IRQHandler [WEAK] + EXPORT DMA2_Channel1_IRQHandler [WEAK] + EXPORT DMA2_Channel2_IRQHandler [WEAK] + EXPORT DMA2_Channel3_IRQHandler [WEAK] + EXPORT DMA2_Channel4_IRQHandler [WEAK] + EXPORT DMA2_Channel5_IRQHandler [WEAK] + EXPORT DMA2_Channel6_IRQHandler [WEAK] + EXPORT DMA2_Channel7_IRQHandler [WEAK] + EXPORT DMAMUX1_OVR_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_PVM_IRQHandler +TAMP_STAMP_LSECSS_SSRU_IRQHandler +RTC_WKUP_IRQHandler +FLASH_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +ADC_IRQHandler +DAC_IRQHandler +C2SEV_PWR_C2H_IRQHandler +COMP_IRQHandler +EXTI9_5_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +LPUART1_IRQHandler +LPTIM1_IRQHandler +LPTIM2_IRQHandler +EXTI15_10_IRQHandler +RTC_Alarm_IRQHandler +LPTIM3_IRQHandler +SUBGHZSPI_IRQHandler +IPCC_C1_RX_IRQHandler +IPCC_C1_TX_IRQHandler +HSEM_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SUBGHZ_Radio_IRQHandler +AES_IRQHandler +RNG_IRQHandler +PKA_IRQHandler +DMA2_Channel1_IRQHandler +DMA2_Channel2_IRQHandler +DMA2_Channel3_IRQHandler +DMA2_Channel4_IRQHandler +DMA2_Channel5_IRQHandler +DMA2_Channel6_IRQHandler +DMA2_Channel7_IRQHandler +DMAMUX1_OVR_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + +;******************************************************************************* +; Element for aligning the Firmware binary size on the AES block size (16 bytes) +;******************************************************************************* + AREA ALIGNTOAESBLOCK, DATA, READONLY, MERGE=1, STRINGS + DCB "0123456789ABCDE",0 + + END + +;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/.cproject new file mode 100644 index 00000000..600b23f4 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/.cproject @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/.project b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/.project new file mode 100644 index 00000000..ce4d1322 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/.project @@ -0,0 +1,236 @@ + + + 1_Image_UserApp + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeExampleProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCUMultiCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Doc/readme.txt + 1 + $%7BPARENT-1-PROJECT_LOC%7D/readme.txt + + + Application/User/com.c + 1 + PARENT-1-PROJECT_LOC/Src/com.c + + + Application/User/common.c + 1 + PARENT-1-PROJECT_LOC/Src/common.c + + + Application/User/flash_if.c + 1 + PARENT-1-PROJECT_LOC/Src/flash_if.c + + + Application/User/fw_update_app.c + 1 + PARENT-1-PROJECT_LOC/Src/fw_update_app.c + + + Application/User/kms_object_update_app.c + 1 + PARENT-1-PROJECT_LOC/Src/kms_object_update_app.c + + + Application/User/main.c + 1 + PARENT-1-PROJECT_LOC/Src/main.c + + + Application/User/se_user_code.c + 1 + PARENT-1-PROJECT_LOC/Src/se_user_code.c + + + Application/User/sfu_app_new_image.c + 1 + PARENT-1-PROJECT_LOC/Src/sfu_app_new_image.c + + + Application/User/stm32wlxx_it.c + 1 + PARENT-1-PROJECT_LOC/Src/stm32wlxx_it.c + + + Application/User/test_protections.c + 1 + PARENT-1-PROJECT_LOC/Src/test_protections.c + + + Application/User/tkms_app.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app.c + + + Application/User/tkms_app_derive_key.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_derive_key.c + + + Application/User/tkms_app_encrypt_decrypt.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_encrypt_decrypt.c + + + Application/User/tkms_app_find.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_find.c + + + Application/User/tkms_app_sign_verify.c + 1 + PARENT-1-PROJECT_LOC/Src/tkms_app_sign_verify.c + + + Application/User/ymodem.c + 1 + PARENT-1-PROJECT_LOC/Src/ymodem.c + + + Drivers/CMSIS/system_stm32wlxx.c + 1 + PARENT-1-PROJECT_LOC/Src/system_stm32wlxx.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_cortex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_cortex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_crc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_crc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_dma.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_dma_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_dma_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_exti.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_exti.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_flash_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_flash_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gpio.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gpio.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_gtzc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_gtzc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_iwdg.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_iwdg.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_pwr_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_pwr_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rcc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rcc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_rtc_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart.c + + + Drivers/STM32WLxx_HAL_Driver/stm32wlxx_hal_uart_ex.c + 1 + PARENT-6-PROJECT_LOC/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_uart_ex.c + + + Middlewares/STM32_Secure_Engine/se_interface_app.o + 1 + PARENT-2-PROJECT_LOC/1_Image_BFU/STM32CubeIDE/Debug/se_interface_app.o + + + Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + 1 + PARENT-6-PROJECT_LOC/Drivers/BSP/STM32WLxx_Nucleo/stm32wlxx_nucleo.c + + + diff --git a/Projects/NUCLEO-WL55JC/Applications/Sigfox/Sigfox_AT_Slave/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/Sigfox/Sigfox_AT_Slave/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/Application/Startup/startup_stm32wl55jcix.s diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM0PLUS/Application/Core/syscalls.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/Application/User/syscalls.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SBSFU/STM32CubeIDE/CM0PLUS/Application/Core/syscalls.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/Application/User/syscalls.c diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/STM32CubeIDE/Application/User/sysmem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/Application/User/sysmem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_SECoreBin/STM32CubeIDE/Application/User/sysmem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/Application/User/sysmem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/UserApp.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/UserApp.ld new file mode 100644 index 00000000..a9d6c851 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/STM32CubeIDE/UserApp.ld @@ -0,0 +1,174 @@ +/* +** LinkerScript +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(APPLI_RAM) + LENGTH(APPLI_RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x800; /* required amount of stack */ + +INCLUDE mapping_fwimg.ld +INCLUDE mapping_sbsfu.ld + +/* Memories definition */ +MEMORY +{ + ISR_VECTOR (rx) : ORIGIN = (SLOT_Active_1_start + 0x200), LENGTH = Vector_size + APPLI_ROM (xrw) : ORIGIN = (SLOT_Active_1_start + Vector_size + 0x200), LENGTH = (SLOT_Active_1_end - SLOT_Active_1_start + 1 - 0x200 - Vector_size) + APPLI_RAM (xrw) : ORIGIN = SB_region_RAM_start, LENGTH = SB_region_RAM_size +} + + +/* Sections */ +SECTIONS +{ + /* The startup code into "ROM" Rom type memory */ + .isr_vector : + { + . = ALIGN(8); + KEEP(*(.isr_vector)) /* Startup code */ + FILL(0); + . = ORIGIN(ISR_VECTOR) + LENGTH(ISR_VECTOR) - 1; + BYTE(0) + . = ALIGN(8); + } >ISR_VECTOR + + .SE_IF_Code : { + KEEP(*se_interface_app.o (.text .text*)) + KEEP(*se_interface_kms.o (.text .text*)) + } >SE_IF_ROM_region + + /* The program code and other data into "ROM" Rom type memory */ + .text : + { + . = ALIGN(8); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(8); + _etext = .; /* define a global symbols at end of code */ + } >APPLI_ROM + + /* Constant data into "ROM" Rom type memory */ + .rodata : + { + . = ALIGN(8); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(8); + } >APPLI_ROM + + .ARM.extab : { + . = ALIGN(8); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(8); + } >APPLI_ROM + + .ARM : { + . = ALIGN(8); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(8); + } >APPLI_ROM + + .preinit_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + } >APPLI_ROM + + .init_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + } >APPLI_ROM + + .fini_array : + { + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + } >APPLI_ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(8); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(8); + _edata = .; /* define a global symbol at data end */ + + } >APPLI_RAM AT> APPLI_ROM + + /* Extra ROM section (last one) to make sure the binary size is a multiple of the AES block size (16 bytes) and F7 flash writing unit (4 bytes)*/ + .align16 : + { + . = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */ + . = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */ + BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */ + } >APPLI_ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(8); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(8); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >APPLI_RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >APPLI_RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/com.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/com.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/com.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/com.c diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/common.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/common.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/common.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/common.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/flash_if.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/flash_if.c new file mode 100644 index 00000000..6ecbce70 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/flash_if.c @@ -0,0 +1,361 @@ +/** + ****************************************************************************** + * @file flash_if.c + * @author MCD Application Team + * @brief FLASH Interface module. + * This file provides set of firmware functions to manage Flash + * Interface functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup USER_APP_COMMON Common + * @{ + */ +/* Includes ------------------------------------------------------------------*/ +#include "flash_if.h" +#include "string.h" +#include + +/* Uncomment the line below if you want some debug logs */ +#define FLASH_IF_DBG +#ifdef FLASH_IF_DBG +#define FLASH_IF_TRACE printf +#else +#define FLASH_IF_TRACE(...) +#endif /* FLASH_IF_DBG */ + + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define NB_PAGE_SECTOR_PER_ERASE 2U /*!< Nb page erased per erase */ +#define EXTERNAL_FLASH_ADDRESS 0x90000000U + + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + + +/* Private function prototypes -----------------------------------------------*/ +static uint32_t GetPage(uint32_t uAddr); +static HAL_StatusTypeDef FLASH_INT_If_Clear_Error(void); + +/* Public functions : wrapper ---------------------------------------------------------*/ + +/** + * @brief Initialize internal and external flash interface (OSPI/QSPI) + * @param none + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_If_Init(void) +{ + HAL_StatusTypeDef e_ret_status = HAL_OK; + + e_ret_status = FLASH_INT_Init(); + if (e_ret_status == HAL_OK) + { + e_ret_status = FLASH_EXT_Init(); + } + return e_ret_status; +} +/** + * @brief Depending on start address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pStart: flash address to be erased + * @param uLength: number of bytes + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_If_Erase_Size(void *pStart, uint32_t uLength) +{ + /* Check Flash start address */ + if ((uint32_t) pStart < EXTERNAL_FLASH_ADDRESS) + { + return FLASH_INT_If_Erase_Size(pStart, uLength); + } + else + { + return FLASH_EXT_If_Erase_Size(pStart, uLength); + } +} + +/** + * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pDestination: flash address to write + * @param pSource: pointer on buffer with data to write + * @param uLength: number of bytes + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_If_Write(void *pDestination, const void *pSource, uint32_t uLength) +{ + /* Check Flash destination address */ + if ((uint32_t) pDestination < EXTERNAL_FLASH_ADDRESS) + { + return FLASH_INT_If_Write(pDestination, pSource, uLength); + } + else + { + return FLASH_EXT_If_Write(pDestination, pSource, uLength); + } +} + +/** + * @brief Depending on destination address, this function will call internal or external (OSPI/QSPI) flash driver + * @brief Depending on source address, this function will call internal or external (OSPI/QSPI) flash driver + * @param pDestination: pointer on buffer to store data + * @param pSource: flash address to read + * @param uLength: number of bytes + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_If_Read(void *pDestination, const void *pSource, uint32_t uLength) +{ + /* Check Flash source address */ + if ((uint32_t) pSource < EXTERNAL_FLASH_ADDRESS) + { + return FLASH_INT_If_Read(pDestination, pSource, uLength); + } + else + { + return FLASH_EXT_If_Read(pDestination, pSource, uLength); + } +} + +/* Public functions : internal flash --------------------------------------------------------- */ +/** + * @brief This function initialize the internal flash interface if required + * @param none + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_INT_Init(void) +{ + return HAL_OK; +} + +/** + * @brief This function does an erase of n (depends on Length) pages in user flash area + * @param pStart: Start of user flash area + * @param uLength: number of bytes. + * @retval HAL status. + */ +HAL_StatusTypeDef FLASH_INT_If_Erase_Size(void *pStart, uint32_t uLength) +{ + uint32_t page_error = 0U; + uint32_t uStart = (uint32_t)pStart; + FLASH_EraseInitTypeDef x_erase_init; + HAL_StatusTypeDef e_ret_status = HAL_ERROR; + uint32_t first_page = 0U; + uint32_t nb_pages = 0U; + uint32_t chunk_nb_pages; + + /* Clear error flags raised during previous operation */ + e_ret_status = FLASH_INT_If_Clear_Error(); + + if (e_ret_status == HAL_OK) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() == HAL_OK) + { + first_page = GetPage(uStart); + /* Get the number of pages to erase from 1st page */ + nb_pages = GetPage(uStart + uLength - 1U) - first_page + 1U; + x_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + /* Erase flash per NB_PAGE_SECTOR_PER_ERASE to avoid watch-dog */ + do + { + chunk_nb_pages = (nb_pages >= NB_PAGE_SECTOR_PER_ERASE) ? NB_PAGE_SECTOR_PER_ERASE : nb_pages; + x_erase_init.Page = first_page; + x_erase_init.NbPages = chunk_nb_pages; + first_page += chunk_nb_pages; + nb_pages -= chunk_nb_pages; + if (HAL_FLASHEx_Erase(&x_erase_init, &page_error) != HAL_OK) + { + HAL_FLASH_GetError(); + e_ret_status = HAL_ERROR; + } + /* Refresh Watchdog */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + } while (nb_pages > 0); + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + HAL_FLASH_Lock(); + + } + else + { + e_ret_status = HAL_ERROR; + } + } + + return e_ret_status; +} + +/** + * @brief This function writes a data buffer in flash (data are 32-bit aligned). + * @note After writing data buffer, the flash content is checked. + * @param pDestination: Start address for target location. It has to be 8 bytes aligned. + * @param pSource: pointer on buffer with data to write + * @param uLength: Length of data buffer in bytes. It has to be 8 bytes aligned. + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_INT_If_Write(void *pDestination, const void *pSource, uint32_t uLength) +{ + HAL_StatusTypeDef e_ret_status = HAL_ERROR; + uint32_t i = 0U; + uint32_t pdata = (uint32_t)pSource; + + /* Clear error flags raised during previous operation */ + e_ret_status = FLASH_INT_If_Clear_Error(); + + if (e_ret_status == HAL_OK) + { + /* Unlock the Flash to enable the flash control register access *************/ + if (HAL_FLASH_Unlock() != HAL_OK) + { + return HAL_ERROR; + + } + else + { + /* DataLength must be a multiple of 64 bit */ + for (i = 0U; i < uLength; i += 8U) + { + /* Device voltage range supposed to be [2.7V to 3.6V], the operation will + be done by word */ + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)pDestination, *((uint64_t *)(pdata + i))) + == HAL_OK) + { + /* Check the written value */ + if (*(uint64_t *)pDestination != *(uint64_t *)(pdata + i)) + { + /* Flash content doesn't match SRAM content */ + e_ret_status = HAL_ERROR; + break; + } + /* Increment FLASH Destination address */ + pDestination = (void *)((uint32_t)pDestination + 8U); + } + else + { + /* Error occurred while writing data in Flash memory */ + e_ret_status = HAL_ERROR; + break; + } + } + /* Lock the Flash to disable the flash control register access (recommended + to protect the FLASH memory against possible unwanted operation) *********/ + HAL_FLASH_Lock(); + } + } + return e_ret_status; +} + +/** + * @brief This function reads flash + * @param pDestination: Start address for target location + * @param pSource: flash address to read + * @param uLength: number of bytes + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_INT_If_Read(void *pDestination, const void *pSource, uint32_t uLength) +{ + memcpy(pDestination, pSource, uLength); + return HAL_OK; +} + +/* Public functions : external flash ---------------------------------------------------------*/ + +HAL_StatusTypeDef FLASH_EXT_Init(void) +{ + return HAL_OK; +} + +/* No external flash available on this product + ==> return SFU_ERROR */ + +HAL_StatusTypeDef FLASH_EXT_If_Erase_Size(void *pStart, uint32_t uLength) +{ + return HAL_ERROR; +} + +HAL_StatusTypeDef FLASH_EXT_If_Write(void *pDestination, const void *pSource, uint32_t uLength) +{ + return HAL_ERROR; +} + +HAL_StatusTypeDef FLASH_EXT_If_Read(void *pDestination, const void *pSource, uint32_t uLength) +{ + return HAL_ERROR; +} + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Clear error flags raised during previous operation + * @param None + * @retval HAL Status. + */ +HAL_StatusTypeDef FLASH_INT_If_Clear_Error(void) +{ + HAL_StatusTypeDef ret = HAL_ERROR; + + /* Unlock the Program memory */ + if (HAL_FLASH_Unlock() == HAL_OK) + { + + /* Clear all FLASH flags */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); + /* Unlock the Program memory */ + if (HAL_FLASH_Lock() == HAL_OK) + { + ret = HAL_OK; + } +#ifdef FLASH_IF_DBG + else + { + FLASH_IF_TRACE("[FLASH_IF] Lock failure\r\n"); + } +#endif /* FLASH_IF_DBG */ + } +#ifdef FLASH_IF_DBG + else + { + FLASH_IF_TRACE("[FLASH_IF] Unlock failure\r\n"); + } +#endif /* FLASH_IF_DBG */ + return ret; +} + +/** + * @brief Gets the page of a given address + * @param Addr: Address of the FLASH Memory + * @retval The page of a given address + */ +uint32_t GetPage(uint32_t Addr) +{ + uint32_t page = 0U; + + page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE; + + return page; +} + + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/fw_update_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/fw_update_app.c new file mode 100644 index 00000000..650c85a9 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/fw_update_app.c @@ -0,0 +1,802 @@ +/** + ****************************************************************************** + * @file fw_update_app.c + * @author MCD Application Team + * @brief Firmware Update module. + * This file provides set of firmware functions to manage Firmware + * Update functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#include "se_def.h" +#include "com.h" +#include "common.h" +#include "flash_if.h" +#include "stm32wlxx_hal.h" +#include "stm32wlxx_nucleo.h" +#include "fw_update_app.h" +#include "se_interface_application.h" +#include "sfu_fwimg_regions.h" +#include "sfu_app_new_image.h" +#include "string.h" +#if defined(__ARMCC_VERSION) +#include "mapping_sbsfu.h" +#elif defined (__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#elif defined(__CC_ARM) +#include "mapping_fwimg.h" +#include "mapping_sbsfu.h" +#endif /* __ARMCC_VERSION */ +#include "ymodem.h" + +/* Private defines -----------------------------------------------------------*/ + +#define ALL_SLOTS 255U /*!< Validate all new firmware installed in a single request */ +/* Global variables ----------------------------------------------------------*/ + +#if !defined(EXTERNAL_LOADER) +static uint32_t m_uFileSizeYmodem = 0U; /*!< Ymodem File size*/ +static uint32_t m_uNbrBlocksYmodem = 0U; /*!< Ymodem Number of blocks*/ +static uint32_t m_uPacketsReceived = 0U; /*!< Ymodem packets received*/ + +#ifdef MINICOM_YMODEM +/* + * With Minicom Ymodem, the data offset is not aligned because PACKET_DATA_INDEX is 7 + * So we cannot write in FLASH with pData as source, we need a copy in an aligned buffer + */ +/* With Minicom YMODEM each packet carries 128 bytes of data */ +static uint8_t alignedBuffer[PACKET_SIZE] __attribute__((aligned(8))); +#endif /* MINICOM_YMODEM */ +#endif /* !EXTERNAL_LOADER */ + +/* Private function prototypes -----------------------------------------------*/ + +#if !defined(EXTERNAL_LOADER) +static HAL_StatusTypeDef FW_UPDATE_DownloadNewFirmware(SFU_FwImageFlashTypeDef *pFwImageDwlArea); +#endif /* !EXTERNAL_LOADER */ + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Run FW Update process. + * @param None + * @retval HAL Status. + */ +#if defined(EXTERNAL_LOADER) +void FW_UPDATE_Run(void) +{ + /* Print Firmware Update welcome message */ + printf("\r\n================ New Fw Download =========================\r\n\n"); + + /* Standalone loader communication : execution requested */ + STANDALONE_LOADER_STATE = STANDALONE_LOADER_DWL_REQ; + + NVIC_SystemReset(); +} + +#else +void FW_UPDATE_Run(void) +{ + HAL_StatusTypeDef ret = HAL_ERROR; + uint8_t fw_header_dwl_slot[SE_FW_HEADER_TOT_LEN]; + SFU_FwImageFlashTypeDef fw_image_dwl_area; + + /* Print Firmware Update welcome message */ + printf("\r\n================ New Fw Download =========================\r\n\n"); + + /* Get Info about the download area */ + SFU_APP_GetDownloadAreaInfo(SLOT_DWL_1, &fw_image_dwl_area); + + /* Download new firmware image*/ + ret = FW_UPDATE_DownloadNewFirmware(&fw_image_dwl_area); + + if (HAL_OK == ret) + { + /* Read header in dwl slot */ + ret = FLASH_If_Read(fw_header_dwl_slot, (void *) fw_image_dwl_area.DownloadAddr, SE_FW_HEADER_TOT_LEN); + + /* Ask for installation at next reset */ + (void)SFU_APP_InstallAtNextReset((uint8_t *) fw_header_dwl_slot); + + /* System Reboot*/ + printf(" -- Image correctly downloaded - reboot\r\n\n"); + HAL_Delay(1000U); + NVIC_SystemReset(); + } + + if (ret != HAL_OK) + { + printf(" -- !!Operation failed!! \r\n\n"); + } +} +#endif /* EXTERNAL_LOADER */ + + +#if defined(EXTERNAL_LOADER) +/** + * @brief Run Multiple FW Update process. + * @param None + * @retval None. + */ +void FW_UPDATE_MULTIPLE_RunMenu(void) +{ + printf(" Feature not supported ! \r\n"); +} + +#else +/** + * @brief Print Multiple FW Update menu. + * @param None + * @retval HAL Status. + */ +static void FW_UPDATE_MULTIPLE_PrintMenu(void) +{ + /* Print Multiple Download menu */ + printf("\r\n============= Multiple Download Menu ================\r\n\n"); + printf(" Download firmware in DWL_SLOT #1 ---------------------- 1\r\n\n"); + printf(" Start installation ------------------------------------ 4\r\n\n"); + printf(" Previous Menu ----------------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} + +/** + * @brief Run Multiple FW Update process. + * @param None + * @retval None. + */ +void FW_UPDATE_MULTIPLE_RunMenu(void) +{ + SFU_FwImageFlashTypeDef fw_image_dwl_area; + uint8_t key = 0U; + uint32_t exit = 0U; + uint32_t i = 0U; + uint32_t several_dwl_area = 1U; + uint32_t slot_number = 0U; + static uint8_t fw_to_install = 0U; + uint8_t fw_header_dwl_slot[SE_FW_HEADER_TOT_LEN]; + + /* Print Menu */ + FW_UPDATE_MULTIPLE_PrintMenu(); + + /* Verify if at least 2 DWL areas exist */ + for (i = 1U; i < SFU_NB_MAX_DWL_AREA; i++) + { + if (SlotStartAdd[SLOT_DWL_1 + i] != 0U) + { + several_dwl_area++; + } + } + + if (several_dwl_area == 1) + { + printf(" -- !!Only 1 download area configured - feature not available!! \r\n\n"); + return; + } + + while (exit == 0U) + { + key = 0U; + slot_number = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the + reload register */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + slot_number = SLOT_DWL_1 + 0U; + break; + case '4' : + /* + * When IMAGE_STATE_HANDLING switch is not activated : + * - requesting installation means writing the header in the SWAP slot then reset. + * - else, reset is enough. Image state set as NEW in the header of dwl_slot will identify the dwl_slot + * to install. + */ + /* Get Info about the download area */ + SFU_APP_GetDownloadAreaInfo(fw_to_install, &fw_image_dwl_area); + + /* Read header in dwl slot */ + FLASH_If_Read(fw_header_dwl_slot, (void *) fw_image_dwl_area.DownloadAddr, SE_FW_HEADER_TOT_LEN); + + /* Ask for installation at next reset */ + (void)SFU_APP_InstallAtNextReset((uint8_t *) fw_header_dwl_slot); + + /* System Reboot*/ + printf(" -- Installation requested - Reboot"); + HAL_Delay(1000U); + NVIC_SystemReset(); + break; + case 'x' : + exit = 1U; + break; + + default: + printf("Invalid Number !\r"); + break; + } + + if (slot_number != 0U) + { + /* Get Info about the download area */ + SFU_APP_GetDownloadAreaInfo(slot_number, &fw_image_dwl_area); + + if ((fw_image_dwl_area.DownloadAddr != 0U) && (fw_image_dwl_area.MaxSizeInBytes != 0U)) + { + /* Download new firmware image*/ + if (FW_UPDATE_DownloadNewFirmware(&fw_image_dwl_area) == HAL_OK) + { + fw_to_install = slot_number; + } + else + { + printf(" -- !!Download failed!! \r\n\n"); + HAL_Delay(1000U); + } + } + else + { + printf(" -- !!Download slot not configured!! \r\n\n"); + HAL_Delay(1000U); + } + } + + /* Print Menu */ + FW_UPDATE_MULTIPLE_PrintMenu(); + } + } +} +#endif /* EXTERNAL_LOADER */ + +#if !defined(EXTERNAL_LOADER) +/** + * @brief Download a new Firmware from the host. + * @retval HAL status + */ +static HAL_StatusTypeDef FW_UPDATE_DownloadNewFirmware(SFU_FwImageFlashTypeDef *pFwImageDwlArea) +{ + HAL_StatusTypeDef ret = HAL_ERROR; + COM_StatusTypeDef e_result; + uint32_t u_fw_size; + YMODEM_CallbacksTypeDef ymodemCb = {Ymodem_HeaderPktRxCpltCallback, Ymodem_DataPktRxCpltCallback}; + + printf(" -- Send Firmware \r\n\n"); + /* Refresh Watchdog */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clear download area */ + printf(" -- -- Erasing download area ...\r\n\n"); + if ((ret = FLASH_If_Erase_Size((void *)(pFwImageDwlArea->DownloadAddr), pFwImageDwlArea->MaxSizeInBytes)) == HAL_OK) + { + /* Download binary */ + printf(" -- -- File> Transfer> YMODEM> Send "); + + /*Init of Ymodem*/ + Ymodem_Init(); + + /*Receive through Ymodem*/ + e_result = Ymodem_Receive(&u_fw_size, pFwImageDwlArea->DownloadAddr, &ymodemCb); + printf("\r\n\n"); + + if ((e_result == COM_OK)) + { + printf(" -- -- Programming Completed Successfully!\r\n\n"); + printf(" -- -- Bytes: %d\r\n\n", u_fw_size); + ret = HAL_OK; + } + else if (e_result == COM_ABORT) + { + printf(" -- -- !!Aborted by user!!\r\n\n"); + ret = HAL_ERROR; + } + else + { + printf(" -- -- !!Error during file download!!\r\n\n"); + ret = HAL_ERROR; + } + } + return ret; +} +#endif /* !(EXTERNAL_LOADER) */ + +#if defined(EXTERNAL_LOADER) +/** + * @brief Run validation of a FW image menu. + * @param None + * @retval None. + */ +void FW_VALIDATE_RunMenu(void) +{ + printf(" Feature not supported ! \r\n"); +} + +#else +#if defined(ENABLE_IMAGE_STATE_HANDLING) +/** + * @brief Display the validation firmware menu choices on hyperterminal + * @param None. + * @retval None. + */ +static void FW_VALIDATE_PrintMenu(void) +{ + printf("\r\n========== Validation of FW Image ============\r\n\n"); + printf(" Validate all firmwares ------------------------- 0\r\n\n"); + printf(" Validate firmware of SLOT_ACTIVE_1 ------------- 1\r\n\n"); + printf(" Validate firmware of SLOT_ACTIVE_2 ------------- 2\r\n\n"); + printf(" Validate firmware of SLOT_ACTIVE_3 ------------- 3\r\n\n"); + printf(" Previous Menu ---------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} +#endif /* (ENABLE_IMAGE_STATE_HANDLING) */ + +/** + * @brief Run validation of a FW image menu. + * @param None + * @retval None. + */ +void FW_VALIDATE_RunMenu(void) +{ +#if defined(ENABLE_IMAGE_STATE_HANDLING) + uint8_t key = 0U; + uint32_t exit = 0U; + uint32_t slot_number = 0U; + SE_ErrorStatus se_retCode = SE_ERROR; + SE_StatusTypeDef se_Status = SE_KO; + SE_FwStateTypeDef fw_state = FWIMG_STATE_INVALID; + + /*Print Main Menu message*/ + FW_VALIDATE_PrintMenu(); + + while (exit == 0U) + { + key = 0U; + slot_number = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload + register */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '0' : + slot_number = VALID_ALL_SLOTS; + break; + case '1' : + slot_number = SLOT_ACTIVE_1; + break; + case '2' : + slot_number = SLOT_ACTIVE_2; + break; + case '3' : + slot_number = SLOT_ACTIVE_3; + break; + case 'x' : + exit = 1U; + break; + default: + printf("Invalid Number !\r"); + break; + } + + if (slot_number != 0U) + { + if ((slot_number != ALL_SLOTS) && (SlotStartAdd[slot_number] == 0U)) + { + printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); + } + else + { + SE_APP_GetActiveFwState(&se_Status, slot_number, &fw_state); + if (fw_state != FWIMG_STATE_SELFTEST ) + { + printf("Firmware not is SELF_TEST state\r\n"); + } + else + { + se_retCode = SE_APP_ValidateFw(&se_Status, slot_number); + if ((SE_SUCCESS == se_retCode) && (SE_OK == se_Status)) + { + printf("Firmware validated\r\n"); + } + else + { + printf("Firmware validation failure\r\n"); + } + } + } + /*Print Main Menu message*/ + FW_VALIDATE_PrintMenu(); + } + } + } +#else + printf(" Feature not supported ! \r\n"); +#endif /* (ENABLE_IMAGE_STATE_HANDLING) */ +} +#endif /* EXTERNAL_LOADER */ + + + +#if !defined(EXTERNAL_LOADER) +/** + * @brief Ymodem Header Packet Transfer completed callback. + * @param uFileSize Dimension of the file that will be received (Bytes). + * @retval None + */ +HAL_StatusTypeDef Ymodem_HeaderPktRxCpltCallback(uint32_t uFileSize) +{ + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + + /*Filesize information is stored*/ + m_uFileSizeYmodem = uFileSize; + + /*Compute the number of blocks */ +#ifndef MINICOM_YMODEM + /* Teraterm sends 1kB YMODEM packets */ + m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (PACKET_1K_SIZE - 1U)) / PACKET_1K_SIZE; +#else + /* Minicom sends 128 bytes YMODEM packets */ + m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (PACKET_SIZE - 1U)) / PACKET_SIZE; +#endif /* MINICOM_YMODEM */ + + /* NOTE : delay inserted for Ymodem protocol*/ + HAL_Delay(1000U); + + return HAL_OK; +} + +/** + * @brief Ymodem Data Packet Transfer completed callback. + * @param pData Pointer to the buffer. + * @param uSize Packet dimension (Bytes). + * @retval None + */ +#ifndef MINICOM_YMODEM +/* Teraterm YMODEM */ +HAL_StatusTypeDef Ymodem_DataPktRxCpltCallback(uint8_t *pData, uint32_t uFlashDestination, uint32_t uSize) +{ + /* Start address of downloaded area : initialized with first packet (header) */ + static uint32_t m_uDwlImgStart = 0U; + + /* End address of downloaded Image : initialized with first packet (header) and checked along download process */ + static uint32_t m_uDwlImgEnd = 0U; + + /* Current destination address for data packet : initialized with first packet (header), incremented at each + flash write */ + static uint32_t m_uDwlImgCurrent = 0U; + + HAL_StatusTypeDef e_ret_status = HAL_OK; + uint32_t uLength; + uint32_t uOldSize; +#if !defined(SFU_NO_SWAP) + SE_FwRawHeaderTypeDef fw_header_dwl; +#endif /* (SFU_NO_SWAP) */ + + m_uPacketsReceived++; + + /*Increase the number of received packets*/ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) /*Last Packet*/ + { + /*Extracting actual payload from last packet*/ + if (0 == (m_uFileSizeYmodem % PACKET_1K_SIZE)) + { + /* The last packet must be fully considered */ + uSize = PACKET_1K_SIZE; + } + else + { + /* The last packet is not full, drop the extra bytes */ + uSize = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / PACKET_1K_SIZE) * PACKET_1K_SIZE); + } + } + + /* First packet : Contains header information: PartialFwSize and PartialFwOffset information */ + if (m_uPacketsReceived == 1) + { + /* Start of Download area */ + m_uDwlImgStart = uFlashDestination; + + /* Initialize Current destination address for data packet */ + m_uDwlImgCurrent = uFlashDestination; + + /* End of Image to be downloaded */ +#if defined(SFU_NO_SWAP) + m_uDwlImgEnd = uFlashDestination + ((SE_FwRawHeaderTypeDef *)pData)->FwSize + SFU_IMG_IMAGE_OFFSET; +#else + m_uDwlImgEnd = uFlashDestination + ((SE_FwRawHeaderTypeDef *)pData)->PartialFwSize + + (((SE_FwRawHeaderTypeDef *)pData)->PartialFwOffset % SLOT_SIZE(SLOT_SWAP)) + + SFU_IMG_IMAGE_OFFSET; +#endif /* SFU_NO_SWAP */ + } + + /* This packet : contains end of FW header */ + if ((m_uDwlImgCurrent < (m_uDwlImgStart + SFU_IMG_IMAGE_OFFSET)) && + ((m_uDwlImgCurrent + uSize) >= (m_uDwlImgStart + SFU_IMG_IMAGE_OFFSET))) + { + /* Write the FW header part (SFU_IMG_IMAGE_OFFSET % PACKET_1K_SIZE bytes length) */ + uLength = SFU_IMG_IMAGE_OFFSET % PACKET_1K_SIZE; + if (uLength == 0) + { + uLength = PACKET_1K_SIZE; + } + if (FLASH_If_Write((void *)m_uDwlImgCurrent, pData, uLength) == HAL_OK) + { +#if defined(SFU_NO_SWAP) + m_uDwlImgCurrent += uLength; +#else + /* + * Read header from dwl area : in some configuration header can be transmitted with 2 YMODEM packets + * ==> pData contains only the last part of the header and cannot be used to retrieve PartialFwOffset + */ + e_ret_status = FLASH_If_Read((uint8_t *)&fw_header_dwl, (void *) m_uDwlImgStart, SE_FW_HEADER_TOT_LEN); + + /* Shift the DWL area pointer, to align image with (PartialFwOffset % sector size) in DWL area */ + m_uDwlImgCurrent += uLength + fw_header_dwl.PartialFwOffset % SLOT_SIZE(SLOT_SWAP); +#endif /* SFU_NO_SWAP */ + + /* Update remaining packet size to write */ + uSize -= uLength; + + /* Update pData pointer to received packet data */ + pData += uLength; + } + else + { + e_ret_status = HAL_ERROR; + } + } + + /* Skip data write if all has been already written as part of the header */ + if (uSize != 0U) + { + /*Adjust dimension to unitary flash programming length */ + if (uSize % FLASH_IF_MIN_WRITE_LEN != 0U) + { + uOldSize = uSize; + uSize += (FLASH_IF_MIN_WRITE_LEN - (uSize % FLASH_IF_MIN_WRITE_LEN)); + m_uDwlImgEnd += (FLASH_IF_MIN_WRITE_LEN - (uSize % FLASH_IF_MIN_WRITE_LEN)); + while (uOldSize < uSize) + { + pData[uOldSize] = 0xFF; + uOldSize++; + } + } + + /* Write Data in Flash - size has to be 64-bit aligned */ + + /* Write in flash only if not beyond allowed area */ + if (((m_uDwlImgCurrent + uSize) <= m_uDwlImgEnd) && (e_ret_status == HAL_OK)) + { + if (FLASH_If_Write((void *)m_uDwlImgCurrent, pData, uSize) == HAL_OK) + { + e_ret_status = HAL_OK; + + /* Move Current destination address for next packet */ + m_uDwlImgCurrent += uSize; + } + else + { + e_ret_status = HAL_ERROR; + } + } + else + { + e_ret_status = HAL_ERROR; + } + } + + /* Last packet : reset m_uPacketsReceived */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + m_uPacketsReceived = 0U; + } + + /* Reset data counters in case of error */ + if (e_ret_status == HAL_ERROR) + { + + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + } + return e_ret_status; +} +#else +/* Minicom YMODEM */ +HAL_StatusTypeDef Ymodem_DataPktRxCpltCallback(uint8_t *pData, uint32_t uFlashDestination, uint32_t uSize) +{ + /* Start address of downloaded area : initialized with first packet (header) */ + static uint32_t m_uDwlImgStart = 0U; + + /* End address of downloaded Image : initialized with first packet (header) and checked along download process */ + static uint32_t m_uDwlImgEnd = 0U; + + /* Current destination address for data packet : initialized with first packet (header), incremented at each + flash write */ + static uint32_t m_uDwlImgCurrent = 0U; + + HAL_StatusTypeDef e_ret_status = HAL_OK; + uint32_t uLength; + uint32_t uOldSize; + SE_FwRawHeaderTypeDef fw_header_dwl; + + m_uPacketsReceived++; + + /*Increase the number of received packets*/ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) /*Last Packet*/ + { + /*Extracting actual payload from last packet*/ + if (0 == (m_uFileSizeYmodem % PACKET_SIZE)) + { + /* The last packet must be fully considered */ + uSize = PACKET_SIZE; + } + else + { + /* The last packet is not full, drop the extra bytes */ + uSize = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / PACKET_SIZE) * PACKET_SIZE); + } + } + + /* First packet : Contains header information: PartialFwSize and PartialFwOffset information */ + if (m_uPacketsReceived == 1) + { + /* Start of Download area */ + m_uDwlImgStart = uFlashDestination; + + /* Initialize Current destination address for data packet */ + m_uDwlImgCurrent = uFlashDestination; + + /* End of Image to be downloaded */ +#if defined(SFU_NO_SWAP) + m_uDwlImgEnd = uFlashDestination + ((SE_FwRawHeaderTypeDef *)pData)->FwSize + SFU_IMG_IMAGE_OFFSET; +#else + m_uDwlImgEnd = uFlashDestination + ((SE_FwRawHeaderTypeDef *)pData)->PartialFwSize + + (((SE_FwRawHeaderTypeDef *)pData)->PartialFwOffset % SLOT_SIZE(SLOT_SWAP)) + + SFU_IMG_IMAGE_OFFSET; +#endif /* SFU_NO_SWAP */ + + } + + /* This packet : contains end of FW header */ + if ((m_uDwlImgCurrent < (m_uDwlImgStart + SFU_IMG_IMAGE_OFFSET)) && + ((m_uDwlImgCurrent + uSize) >= (m_uDwlImgStart + SFU_IMG_IMAGE_OFFSET))) + { + /* Write the FW header part (SFU_IMG_IMAGE_OFFSET % PACKET_1K_SIZE bytes length) */ + uLength = SFU_IMG_IMAGE_OFFSET % PACKET_SIZE; + if (uLength == 0) + { + uLength = PACKET_SIZE; + } + + memcpy(alignedBuffer, pData, uLength); + + if (FLASH_If_Write((void *)m_uDwlImgCurrent, alignedBuffer, uLength) == HAL_OK) + { +#if defined(SFU_NO_SWAP) + m_uDwlImgCurrent += uLength; +#else + /* + * Read header from dwl area : in some configuration header can be transmitted with 2 YMODEM packets + * ==> pData contains only the last part of the header and cannot be used to retrieve PartialFwOffset + */ + e_ret_status = FLASH_If_Read((uint8_t *)&fw_header_dwl, (void *) m_uDwlImgStart, SE_FW_HEADER_TOT_LEN); + /* Shift the DWL area pointer, to align image with (PartialFwOffset % sector size) in DWL area */ + m_uDwlImgCurrent += uLength + fw_header_dwl.PartialFwOffset % SLOT_SIZE(SLOT_SWAP); +#endif /* SFU_NO_SWAP */ + + /* Update remaining packet size to write */ + uSize -= uLength; + + /* Update pData pointer to received packet data */ + pData += uLength; + } + else + { + e_ret_status = HAL_ERROR; + } + } + /* Skip data write if all has been already written as part of the header */ + if (uSize != 0U) + { + /*Adjust dimension to unitary flash programming length */ + if (uSize % FLASH_IF_MIN_WRITE_LEN != 0U) + { + uOldSize = uSize; + uSize += (FLASH_IF_MIN_WRITE_LEN - (uSize % FLASH_IF_MIN_WRITE_LEN)); + m_uDwlImgEnd += (FLASH_IF_MIN_WRITE_LEN - (uSize % FLASH_IF_MIN_WRITE_LEN)); + while (uOldSize < uSize) + { + pData[uOldSize] = 0xFF; + uOldSize++; + } + } + + /* Write Data in Flash - size has to be 64-bit aligned */ + + + /* Write in flash only if not beyond allowed area */ + if (((m_uDwlImgCurrent + uSize) <= m_uDwlImgEnd) && (e_ret_status == HAL_OK)) + { + memcpy(alignedBuffer, pData, uSize); + + if (FLASH_If_Write((void *)m_uDwlImgCurrent, alignedBuffer, uSize) == HAL_OK) + { + e_ret_status = HAL_OK; + + /* Move Current destination address for next packet */ + m_uDwlImgCurrent += uSize; + } + else + { + e_ret_status = HAL_ERROR; + } + } + else + { + e_ret_status = HAL_ERROR; + } + } + + /* Last packet : reset m_uPacketsReceived */ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) + { + m_uPacketsReceived = 0U; + } + + /* Reset data counters in case of error */ + if (e_ret_status == HAL_ERROR) + { + + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + } + return e_ret_status; +} +#endif /* MINICOM_YMODEM */ +#endif /* !(EXTERNAL_LOADER) */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/kms_object_update_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/kms_object_update_app.c new file mode 100644 index 00000000..477c6f64 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/kms_object_update_app.c @@ -0,0 +1,337 @@ +/** + ****************************************************************************** + * @file kms_object_update_app.c + * @author MCD Application Team + * @brief Firmware Update module. + * This file provides set of firmware functions to manage KMS + * Update functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "se_def.h" +#include "com.h" +#include "common.h" +#include "flash_if.h" +#include "ymodem.h" +#include "stm32wlxx_hal.h" +#include "fw_update_app.h" + +#include "sfu_app_new_image.h" +#include "sfu_fwimg_regions.h" + +#include "string.h" + +#include "kms.h" +#include "pkcs11.h" +#include "kms_blob_metadata.h" + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup FW_UPDATE Firmware Update Example + * @{ + */ +static uint32_t m_uFileSizeYmodem = 0U; /* !< Ymodem File size*/ +static uint32_t m_uNbrBlocksYmodem = 0U; /* !< Ymodem Number of blocks*/ +static uint32_t m_uPacketsReceived = 0U; /* !< Ymodem packets received*/ + + +/** @defgroup FW_UPDATE_Private_Functions Private Functions + * @{ + */ +static void KMS_UPDATE_PrintMenu(void); +static HAL_StatusTypeDef KMS_UPDATE_ImportBlob(SFU_FwImageFlashTypeDef *pFwImageDwlArea); + +HAL_StatusTypeDef KMS_UPDATE_GetDownloadAreaInfo(SFU_FwImageFlashTypeDef *pArea); +void KMS_UPDATE_StartLocalUpdate(void); + + +HAL_StatusTypeDef Ymodem_BlobHeaderPktRxCpltCallback(uint32_t uFileSize); +HAL_StatusTypeDef Ymodem_BlobDataPktRxCpltCallback(uint8_t *pData, uint32_t uFlashDestination, uint32_t uSize); + +/** + * @} + */ +/** @defgroup FW_UPDATE_Exported_Functions Exported Functions + * @{ + */ + +/** @defgroup FW_UPDATE_Control_Functions Control Functions + * @{ + */ + +/** + * @brief Provide the area descriptor to write a KMS image in Flash. + * This function is used by the User Application to know where to store a new KMS Blob Image before asking for + * its installation. + * @param pArea pointer to area descriptor + * @retval HAL_OK if successful, otherwise HAL_ERROR + */ +HAL_StatusTypeDef KMS_UPDATE_GetDownloadAreaInfo(SFU_FwImageFlashTypeDef *pArea) +{ + HAL_StatusTypeDef ret; + if (pArea != NULL) + { + pArea->DownloadAddr = SlotStartAdd[SLOT_DWL_1]; + pArea->MaxSizeInBytes = (uint32_t)SLOT_SIZE(SLOT_DWL_1); + pArea->ImageOffsetInBytes = SFU_IMG_IMAGE_OFFSET; + ret = HAL_OK; + } + else + { + ret = HAL_ERROR; + } + return ret; +} + + +/** + * @brief Run KMS Blob Update process. + * @param None + * @retval HAL Status. + */ +void KMS_UPDATE_StartLocalUpdate(void) +{ + HAL_StatusTypeDef ret = HAL_ERROR; + uint8_t fw_header_input[SE_FW_HEADER_TOT_LEN]; + SFU_FwImageFlashTypeDef fw_image_dwl_area; + + /* Print Firmware Update welcome message */ + KMS_UPDATE_PrintMenu(); + + /* Get Info about the download area */ + if (KMS_UPDATE_GetDownloadAreaInfo(&fw_image_dwl_area) != HAL_ERROR) + { + /* Download new blob image*/ + ret = KMS_UPDATE_ImportBlob(&fw_image_dwl_area); + + if (HAL_OK == ret) + { + /* Read header in SWAP Area */ + (void)memcpy(fw_header_input, (uint32_t *)(fw_image_dwl_area.DownloadAddr), sizeof(fw_header_input)); + + /* Ask for installation at next reset */ + /* FOR KMS, data are directly written to the SWAP Area. */ + /* So in the next reset, we will detect that a KMS Header is present */ + /* This will launch a call to KMS ImportBlob */ + + /* System Reboot*/ + (void)printf(" -- Image correctly downloaded - reboot\r\n\n"); + HAL_Delay(1000U); + NVIC_SystemReset(); + } + } + + if (ret != HAL_OK) + { + (void)printf(" -- !!Operation failed!! \r\n\n"); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FW_UPDATE_Private_Functions + * @{ + */ + +/** + * @brief Display the KMS Main Menu choices on HyperTerminal + * @param None. + * @retval None. + */ +static void KMS_UPDATE_PrintMenu(void) +{ + (void)printf("\r\n================ New KMS Blob Download =========================\r\n\n"); +} + +/** + * @brief Download a new BLOB from the host. + * @retval HAL status + */ +static HAL_StatusTypeDef KMS_UPDATE_ImportBlob(SFU_FwImageFlashTypeDef *pFwImageDwlArea) +{ + HAL_StatusTypeDef ret; + COM_StatusTypeDef e_result; + uint32_t u_fw_size; + YMODEM_CallbacksTypeDef ymodemCb = {Ymodem_BlobHeaderPktRxCpltCallback, Ymodem_BlobDataPktRxCpltCallback}; + + (void)printf(" -- Send KMS Blob \r\n\n"); + /* Refresh Watchdog */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clear download area */ + (void)printf(" -- -- Erasing download area ...\r\n\n"); + ret = FLASH_If_Erase_Size((uint32_t *)(pFwImageDwlArea->DownloadAddr), pFwImageDwlArea->MaxSizeInBytes); + if (ret == HAL_OK) + { + /* Download binary */ + (void)printf(" -- -- File> Transfer> YMODEM> Send "); + + /*Init of Ymodem*/ + Ymodem_Init(); + + /*Receive through Ymodem*/ + e_result = Ymodem_Receive(&u_fw_size, pFwImageDwlArea->DownloadAddr, &ymodemCb); + (void)printf("\r\n\n"); + + if ((e_result == COM_OK)) + { + (void)printf(" -- -- Programming Completed Successfully!\r\n\n"); + (void)printf(" -- -- Bytes: %d\r\n\n", u_fw_size); + ret = HAL_OK; + } + else if (e_result == COM_ABORT) + { + (void)printf(" -- -- !!Aborted by user!!\r\n\n"); + ret = HAL_ERROR; + } + else + { + (void)printf(" -- -- !!Error during file download!!\r\n\n"); + ret = HAL_ERROR; + } + } + return ret; +} + +/** + * @brief Ymodem Header Packet Transfer completed callback. + * @param uFileSize Dimension of the file that will be received (Bytes). + * @retval None + */ +HAL_StatusTypeDef Ymodem_BlobHeaderPktRxCpltCallback(uint32_t uFileSize) +{ + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + + /*Filesize information is stored*/ + m_uFileSizeYmodem = uFileSize; + + /* compute the number of 1K blocks */ + m_uNbrBlocksYmodem = (m_uFileSizeYmodem + (PACKET_1K_SIZE - 1U)) / PACKET_1K_SIZE; + + /* NOTE : delay inserted for Ymodem protocol*/ + HAL_Delay(1000U); + + return HAL_OK; +} + +/** + * @brief Ymodem Data Packet Transfer completed callback. + * @param pData Pointer to the buffer. + * @param uSize Packet dimension (Bytes). + * @retval None + */ +HAL_StatusTypeDef Ymodem_BlobDataPktRxCpltCallback(uint8_t *pData, uint32_t uFlashDestination, uint32_t uSize) +{ + /* End address of downloaded Image : initialized with first packet (header) and checked along download process */ + static uint32_t m_uDwlImgEnd = 0U; + /* Current destination address for data packet : initialized with first packet (header), incremented at each flash + write */ + static uint32_t m_uDwlImgCurrent = 0U; + uint32_t tmpSize = uSize; + + HAL_StatusTypeDef e_ret_status; + + m_uPacketsReceived++; + + /*Increase the number of received packets*/ + if (m_uPacketsReceived == m_uNbrBlocksYmodem) /*Last Packet*/ + { + /*Extracting actual payload from last packet*/ + if (0UL == (m_uFileSizeYmodem % PACKET_1K_SIZE)) + { + /* The last packet must be fully considered */ + tmpSize = PACKET_1K_SIZE; + } + else + { + /* The last packet is not full, drop the extra bytes */ + tmpSize = m_uFileSizeYmodem - ((uint32_t)(m_uFileSizeYmodem / PACKET_1K_SIZE) * PACKET_1K_SIZE); + } + + m_uPacketsReceived = 0U; + } + + /* First packet : Contains the FW header */ + if (m_uPacketsReceived == 1UL) + { + /* End of Image to be downloaded */ + m_uDwlImgEnd = uFlashDestination + ((KMS_BlobRawHeaderTypeDef *)(uint32_t)pData)->BlobSize + KMS_BLOB_IMG_OFFSET; + /* Initialize Current destination address for data packet */ + m_uDwlImgCurrent = uFlashDestination; + } + + /*Adjust dimension to 64-bit length */ + if ((tmpSize % FLASH_IF_MIN_WRITE_LEN) != 0U) + { + tmpSize += (FLASH_IF_MIN_WRITE_LEN - (tmpSize % FLASH_IF_MIN_WRITE_LEN)); + m_uDwlImgEnd += (FLASH_IF_MIN_WRITE_LEN - (tmpSize % FLASH_IF_MIN_WRITE_LEN)); + } + + /* Write Data in Flash - size has to be 64-bit aligned */ + + /* Write in flash only if not beyond allowed area */ + if ((m_uDwlImgCurrent + tmpSize) <= m_uDwlImgEnd) + { + if (FLASH_If_Write((uint32_t *)m_uDwlImgCurrent, pData, tmpSize) == HAL_OK) + { + e_ret_status = HAL_OK; + m_uDwlImgCurrent += tmpSize; + } + else + { + e_ret_status = HAL_ERROR; + } + } + else + { + e_ret_status = HAL_ERROR; + } + + if (e_ret_status == HAL_ERROR) + { + + /*Reset of the ymodem variables */ + m_uFileSizeYmodem = 0U; + m_uPacketsReceived = 0U; + m_uNbrBlocksYmodem = 0U; + } + return e_ret_status; +} + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/main.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/main.c new file mode 100644 index 00000000..478218a4 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/main.c @@ -0,0 +1,303 @@ +/** + ****************************************************************************** + * @file main.c + * @author MCD Application Team + * @brief Main application file. + * This application demonstrates Firmware Update, protections + * and crypto testing functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "se_def.h" +#include "flash_if.h" +#include "se_interface_application.h" +#include "common.h" +#include "test_protections.h" +#include "fw_update_app.h" +#include "se_user_code.h" +#ifdef KMS_ENABLED +#include "tkms.h" +#include "tkms_app.h" +#endif /* KMS_ENABLED */ + + +/** @addtogroup USER_APP User App Example + * @{ + */ + + +/** @addtogroup USER_APP_COMMON Common + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define USER_APP_NBLINKS ((uint8_t) 1U) +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +uint8_t *pUserAppId; +const uint8_t UserAppId = 'A'; +SE_ErrorStatus eRetStatus = SE_ERROR; +SE_StatusTypeDef eStatus; + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +void FW_APP_PrintMainMenu(void); +void FW_APP_Run(void); + +/** + * @brief Main program + * @param None + * @retval None + */ +int main(void) +{ + uint32_t i = 0U; + /* set example to const : this const changes in binary without rebuild */ + pUserAppId = (uint8_t *)&UserAppId; + + /* STM32WLxx HAL library initialization: + - Configure the Flash prefetch + - Systick timer is configured by default as source of time base, but user + can eventually implement his proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and + handled in milliseconds basis. + - Set NVIC Group Priority to 4 + - Low Level Initialization + */ + HAL_Init(); + + + /* Configure the system clock */ + SystemClock_Config(); + + /* Flash driver initialization*/ + FLASH_If_Init(); + + /* Board BSP Configuration-------------------------------------------------*/ + + /* LED Init*/ + BSP_LED_Init(LED_GREEN); + for (i = 0U; i < USER_APP_NBLINKS; i++) + { + BSP_LED_Toggle(LED_GREEN); + HAL_Delay(100U); + BSP_LED_Toggle(LED_GREEN); + HAL_Delay(100U); + BSP_LED_Toggle(LED_GREEN); + HAL_Delay(100U); + BSP_LED_Toggle(LED_GREEN); + HAL_Delay(100U); + } + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload register*/ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Configure Communication module */ + COM_Init(); + + /* Configure button in EXTI mode */ + BUTTON_INIT_EXTI(); + + printf("\r\n======================================================================"); + printf("\r\n= (C) COPYRIGHT 2017 STMicroelectronics ="); + printf("\r\n= ="); + printf("\r\n= User App #%c =", *pUserAppId); + printf("\r\n======================================================================"); + printf("\r\n\r\n"); + + + /* User App firmware runs*/ + FW_APP_Run(); + + while (1U) + {} + +} + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSI) + * SYSCLK(Hz) = 48000000 + * HCLK(Hz) = 48000000 + * HCLK1 Prescaler = 1 + * HCKL2 Prescaler = 1 + * HCKL3 Prescaler = 1 + * APB1 Prescaler = 1 + * APB2 Prescaler = 1 + * HSI Frequency(Hz) = 16000000 + * PLL_M = 2 //not considered on FPGA as VCO output is fixed at 240Mhz + * PLL_N = 30 //not considered on FPGA as VCO output is fixed at 240Mhz + * PLL_N = 20 //Allow to fix VCO to 160Mhz, and reach Sysclk Max Frqe = 32MHz + * with PLL_DIV5 + * PLL_P = 5 + * PLL_Q = 5 + * PLL_R = 5 + * Flash Latency(WS) = 2 + * @param None + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + /* Activate PLL with HSI as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.HSICalibrationValue = 70; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2; + RCC_OscInitStruct.PLL.PLLN = 20; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV5; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV5; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + /* Initialization Error */ + while (1); + } + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2\ + | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK3); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1; + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + /* Initialization Error */ + while (1); + } +} + + +/** + * @brief Display the TEST Main Menu choices on HyperTerminal + * @param None. + * @retval None. + */ +void FW_APP_PrintMainMenu(void) +{ + printf("\r\n=================== Main Menu ============================\r\n\n"); + printf(" Download a new Fw Image ------------------------------- 1\r\n\n"); + printf(" Test Protections -------------------------------------- 2\r\n\n"); + printf(" Test SE User Code ------------------------------------- 3\r\n\n"); + printf(" Multiple download ------------------------------------- 4\r\n\n"); + printf(" Validate a FW Image------------------------------------ 5\r\n\n"); +#ifdef KMS_ENABLED + printf(" Test tKMS --------------------------------------------- a\r\n\n"); +#endif /* KMS_ENABLED */ + printf(" Selection :\r\n\n"); +} + +/** + * @brief Display the TEST Main Menu choices on HyperTerminal + * @param None. + * @retval None. + */ +void FW_APP_Run(void) +{ + uint8_t key = 0U; + + /* Print Main Menu message*/ + FW_APP_PrintMainMenu(); + + while (1U) + { + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload + register */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + FW_UPDATE_Run(); + break; + case '2' : + TEST_PROTECTIONS_RunMenu(); + break; + case '3' : + SE_USER_CODE_RunMenu(); + break; + case '4' : + FW_UPDATE_MULTIPLE_RunMenu(); + break; + case '5' : + FW_VALIDATE_RunMenu(); + break; +#ifdef KMS_ENABLED + case 'a' : + tkms_app_menu(); + break; +#endif /* KMS_ENABLED */ + default: + printf("Invalid Number !\r"); + break; + } + + /*Print Main Menu message*/ + FW_APP_PrintMainMenu(); + } + + BSP_LED_Toggle(LED_GREEN); + } +} + + +#ifdef USE_FULL_ASSERT + +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + + /* Infinite loop */ + while (1U) + { + } +} +#endif /* USE_FULL_ASSERT */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/se_user_code.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/se_user_code.c new file mode 100644 index 00000000..894f1ed6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/se_user_code.c @@ -0,0 +1,191 @@ +/** + ****************************************************************************** + * @file se_user_code.c + * @author MCD Application Team + * @brief Secure Engine User code example module. + * This file demonstrates how to call user defined services running + * in Secure Engine. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "se_def.h" +#include "com.h" +#include "common.h" +#include "stm32wlxx_hal.h" +#include "stm32wlxx_nucleo.h" +#include "se_user_code.h" +#include "se_interface_application.h" +#include "sfu_fwimg_regions.h" +#include /* needed for memset */ + + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup SE_USER_CODE Secure Engine User Code Example + * @brief Example of user defined code running in Secure Engine. + * This code provides user defined services to the user application. + * @{ + */ + +/** @defgroup SE_USER_CODE_Private_Variables Private Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup SE_USER_CODE_Private_Functions Private Functions + * @{ + */ + +/** + * @brief Display the SE_USER_CODE Menu choices on hyperterminal + * @param None. + * @retval None. + */ +static void SE_USER_CODE_PrintMenu(void) +{ + printf("\r\n=== Call User Defined Code running in Secure Engine ===\r\n\n"); + printf(" Get firmware information of SLOT_ACTIVE_1 ------------- 1\r\n\n"); + printf(" Previous Menu ----------------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} + +/** + * @brief Get FW information. + * @param SlotNumber slot identification + * @retval HAL Status. + */ +static void SE_USER_CODE_GetFwInfo(uint32_t SlotNumber) +{ + SE_ErrorStatus se_retCode = SE_ERROR; + SE_StatusTypeDef se_Status = SE_KO; + SE_APP_ActiveFwInfo_t sl_FwInfo; + + memset(&sl_FwInfo, 0xFF, sizeof(SE_APP_ActiveFwInfo_t)); + + + + /* Get FW info */ + se_retCode = SE_APP_GetActiveFwInfo(&se_Status, SlotNumber, &sl_FwInfo); + + if ((SE_SUCCESS == se_retCode) && (SE_OK == se_Status)) + { + /* Print the result */ + printf("Firmware Info:\r\n"); + printf("\tActiveFwVersion: %d\r\n", sl_FwInfo.ActiveFwVersion); + printf("\tActiveFwSize: %d bytes\r\n", sl_FwInfo.ActiveFwSize); + } + else + { + /* Failure */ + printf(" -- !!Operation failed!! \r\n\n"); + } + +} + + +/** + * @} + */ + +/** @addtogroup SE_USER_CODE_Exported_Functions + * @{ + */ + +/** + * @brief Run get firmware info menu. + * @param None + * @retval HAL Status. + */ +void SE_USER_CODE_RunMenu(void) +{ + uint8_t key = 0U; + uint32_t exit = 0U; + uint32_t slot_number = 0U; + + /*Print Main Menu message*/ + SE_USER_CODE_PrintMenu(); + + while (exit == 0U) + { + key = 0U; + slot_number = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload + register */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + slot_number = SLOT_ACTIVE_1; + if (SlotStartAdd[slot_number] == 0U) + { + printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); + } + else + { + SE_USER_CODE_GetFwInfo(slot_number); + } + break; + case 'x' : + exit = 1U; + break; + default: + printf("Invalid Number !\r"); + break; + } + + if (exit != 1U) + { + if (SlotStartAdd[slot_number] == 0U) + { + printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); + } + else + { + SE_USER_CODE_GetFwInfo(slot_number); + } + + /*Print Main Menu message*/ + SE_USER_CODE_PrintMenu(); + } + } + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/sfu_app_new_image.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/sfu_app_new_image.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/sfu_app_new_image.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/sfu_app_new_image.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/stm32wlxx_it.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/stm32wlxx_it.c new file mode 100644 index 00000000..2f44492a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/stm32wlxx_it.c @@ -0,0 +1,220 @@ +/** + ****************************************************************************** + * @file stm32wlxx_it.c + * @author MCD Application Team + * @brief Main Interrupt Service Routines. + * This file provides template for all exceptions handler and + * peripherals interrupt service routine. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32wlxx_it.h" +#include "test_protections.h" + +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup USER_APP_COMMON Common + * @{ + */ +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +RTC_HandleTypeDef RtcHandle; +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + * @param None + * @retval None + */ +void NMI_Handler(void) +{ + /* Go to infinite loop when NMI exception occurs */ + while (1) + { + printf("NMI exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Hard Fault exception. + * @param None + * @retval None + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + printf("Hard Fault exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Memory Manage exception. + * @param None + * @retval None + */ +void MemManage_Handler(void) +{ + /* Go to infinite loop when Memory Manage exception occurs */ + while (1) + { + printf("Memory Manage exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Bus Fault exception. + * @param None + * @retval None + */ +void BusFault_Handler(void) +{ + /* Go to infinite loop when Bus Fault exception occurs */ + while (1) + { + printf("Bus Fault exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles Usage Fault exception. + * @param None + * @retval None + */ +void UsageFault_Handler(void) +{ + /* Go to infinite loop when Usage Fault exception occurs */ + while (1) + { + printf("Usage Fault exception!\r"); + NVIC_SystemReset(); + } +} + +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +void SVC_Handler(void) +{ +} + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) +{ +} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +void PendSV_Handler(void) +{ +} + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +void SysTick_Handler(void) +{ + HAL_IncTick(); +} + +/******************************************************************************/ +/* STM32WLxx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32wlxx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles Flash operation error interrupt request. + * @param None + * @retval None + */ +void FLASH_IRQHandler(void) +{ + HAL_FLASH_IRQHandler(); +} + +/** + * @brief This function handles Tamper interrupt request. + * @param None + * @retval None + */ +void TAMP_STAMP_LSECSS_SSRU_IRQHandler() +{ + /* Store in the handle the Internal Tamper enabled */ + SET_BIT(RtcHandle.IsEnabled.TampFeatures, RTC_TAMPER_ID); + + RtcHandle.Instance = RTC; + HAL_RTCEx_TamperIRQHandler(&RtcHandle); +} + +void BUTTON_IRQHANDLER(void) +{ + HAL_GPIO_EXTI_IRQHandler(BUTTON_EXTI_LINE); +} + +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + if (GPIO_Pin == BUTTON_EXTI_LINE) + { + printf("\r\nUser IRQ Handler: User Button pressed\r\n"); + } +} + +/** + * @brief This function handles PPP interrupt request. + * @param None + * @retval None + */ +/*void PPP_IRQHandler(void) +{ +}*/ + + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/system_stm32wlxx.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/system_stm32wlxx.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/system_stm32wlxx.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/system_stm32wlxx.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/test_protections.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/test_protections.c new file mode 100644 index 00000000..38b51f1a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/test_protections.c @@ -0,0 +1,458 @@ +/** + ****************************************************************************** + * @file test_protections.c + * @author MCD Application Team + * @brief Test Protections module. + * This file provides set of firmware functions to manage Test Protections + * functionalities. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#define TEST_PROTECTIONS_C + +/* Includes ------------------------------------------------------------------*/ +#include +#include "test_protections.h" +#include "se_def.h" +#include "se_interface_application.h" +#include "com.h" +#include "common.h" +#include "flash_if.h" +#include "sfu_fwimg_regions.h" /* required for corruption tests (a real user application should NOT need this file) */ +#if defined(__ARMCC_VERSION) +#include "mapping_sbsfu.h" +#elif defined (__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __ARMCC_VERSION */ +/** @addtogroup USER_APP User App Example + * @{ + */ + +/** @addtogroup TEST_PROTECTIONS Test protections + * @{ + */ + +/** @defgroup TEST_PROTECTIONS_Private_Defines Private Defines + * @{ + */ + +/** + * @brief Isolated enclave Test. + */ +/*!< Address used to test SE CODE protection*/ +#define TEST_PROTECTIONS_SE_ISOLATED_CODE_FLASH_ADDRESS ((uint32_t) SE_CALLGATE_REGION_ROM_START) +/*!< Address used to test SE VDATA protection*/ +#define TEST_PROTECTIONS_SE_ISOLATED_VDATA_SRAM_ADDRESS ((uint32_t) SE_REGION_RAM_START) + +/** + * @brief WRP Test. + */ +/*!< Address used to test WRP protection */ +#define TEST_PROTECTIONS_WRP_FLASH_ADDRESS ((uint32_t) (KMS_DATASTORAGE_START - 0x1000)) +/*!< WRP Test Size */ +#define TEST_PROTECTIONS_WRP_FLASH_SIZE ((uint32_t)0x800U) + +/** + * @brief IWDG Test. + */ +/*!< IWDG Test delay in ms (it has to be greater than what used in SB)*/ +#define TEST_PROTECTIONS_IWDG_DELAY ((uint32_t)10000U) + +/** + * @brief TAMPER Test. + */ +#define TEST_PROTECTIONS_TAMPER_DELAY ((uint32_t)10U) /*!< TAMPER Test delay in s */ + +/** + * @brief CORRUPT_IMAGE Test. + */ +/*!< CORRUPT_IMAGE Test: address where data will be corrupted: address of active slot + offset */ +#define TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(A) ((uint32_t)(SlotStartAdd[A] \ + +SFU_IMG_IMAGE_OFFSET)) +/*!< CORRUPT_IMAGE Test: size of data to be corrupted */ +#define TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE ((uint32_t)32U) + +/** @defgroup TEST_PROTECTIONS_Private_Variables Private Variables + * @{ + */ +static uint8_t uRead_WRP[TEST_PROTECTIONS_WRP_FLASH_SIZE]; /*!< RTC handler used for TAMPER Test */ +static uint32_t m_uTamperEvent = 0U; /*!< Tamper Event */ + +/** @defgroup TEST_PROTECTIONS_Private_Functions Private Functions + * @{ + */ +static void TEST_PROTECTIONS_RunWRP(void); +static void TEST_PROTECTIONS_RunTAMPER(void); +static void TEST_PROTECTIONS_RunIWDG(void); +static void TEST_PROTECTIONS_CORRUPT_RunMenu(void); +static void TEST_PROTECTIONS_PrintTestingMenu(void); +/** + * @} + */ + + + + +/** @defgroup TEST_PROTECTIONS_Exported_Functions Exported Functions + * @{ + */ + +/** @defgroup TEST_PROTECTIONS_Control_Functions Control Functions + * @{ + */ + +/** + * @brief Display the TEST Main Menu choices on HyperTerminal + * @param None. + * @retval None. + */ +void TEST_PROTECTIONS_RunMenu(void) +{ + uint8_t key = 0U; + uint8_t exit = 0U; + + /* Print Main Menu message */ + TEST_PROTECTIONS_PrintTestingMenu(); + + while (exit == 0U) + { + key = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the + reload register*/ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + TEST_PROTECTIONS_CORRUPT_RunMenu(); + break; + case '2' : + TEST_PROTECTIONS_RunWRP(); + break; + case '3' : + TEST_PROTECTIONS_RunIWDG(); + break; + case '4' : + TEST_PROTECTIONS_RunTAMPER(); + break; + case 'x' : + exit = 1U; + break; + + default: + printf("Invalid Number !\r"); + break; + } + /*Print Main Menu message*/ + TEST_PROTECTIONS_PrintTestingMenu(); + } + } +} + + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup TEST_PROTECTIONS_Private_Functions + * @{ + */ + +/** + * @brief Display the TEST Main Menu choices on HyperTerminal + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_PrintTestingMenu(void) +{ + printf("\r\n=================== Test Menu ============================\r\n\n"); + printf(" Test : CORRUPT ACTIVE IMAGE --------------------------- 1\r\n\n"); + printf(" Test Protection: WRP ---------------------------------- 2\r\n\n"); + printf(" Test Protection: IWDG --------------------------------- 3\r\n\n"); + printf(" Test Protection: TAMPER ------------------------------- 4\r\n\n"); + printf(" Previous Menu ----------------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} + + +/** + * @brief TEST Run WRP + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunWRP(void) +{ + uint32_t i = 0U; + uint32_t address = 0U; + + printf("\r\n====== Test Protection: WRP ===========================\r\n\n"); + + address = TEST_PROTECTIONS_WRP_FLASH_ADDRESS; + + /* 1 - Read Page to be used for restoring*/ + printf(" -- Reading 0x%x bytes at address: 0x%x (for backup)\r\n\n", TEST_PROTECTIONS_WRP_FLASH_SIZE, + TEST_PROTECTIONS_WRP_FLASH_ADDRESS); + + for (i = 0U; i < TEST_PROTECTIONS_WRP_FLASH_SIZE; i++) + { + uRead_WRP[i] = *((uint8_t *)(address + i)); + } + + /* 2 - Erasing page */ + printf(" -- Erasing 0x%x bytes at address: 0x%x\r\n\n", TEST_PROTECTIONS_WRP_FLASH_SIZE, + TEST_PROTECTIONS_WRP_FLASH_ADDRESS); + + /* Check that it is not allowed to erase this page */ + if (FLASH_If_Erase_Size((void *)address, TEST_PROTECTIONS_WRP_FLASH_SIZE) != HAL_OK) + { + /* Error returned during programmation. */ + /* Check that WRPERR flag is set */ + if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) != 0U) + { + printf("-- !! HAL_FLASH_ERROR_WRP: FLASH Write protected error flag !!\r\n\n"); + } + } + else + { + /* 3 - Writing Data previously read*/ + if (FLASH_If_Write((void *)address, uRead_WRP, TEST_PROTECTIONS_WRP_FLASH_SIZE) != HAL_OK) + { + /* Error returned during programmation. */ + printf("-- !! HAL_FLASH_ERROR: FLASH Write error\r\n\n"); + + /* Check that WRPERR flag is set */ + if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) != 0U) + { + printf("-- !! HAL_FLASH_ERROR_WRP: FLASH Write protected error flag !!\r\n\n"); + } + } + else + { + printf(" -- Written successfully at address: 0x%x\r\n\n", TEST_PROTECTIONS_WRP_FLASH_ADDRESS); + + /*No Errors detected means WRP was not enabled*/ + printf(" -- !! WRP protection is NOT ENABLED !!\r\n\n"); + } + } +} + +/** + * @brief TEST Run CORRUPT_IMAGE + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunCORRUPT(uint32_t slot_number) +{ + HAL_StatusTypeDef ret = HAL_ERROR; + uint8_t pattern[TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE] = {0}; + + /* On this series, there is no MPU to disable to allow flash corruption. */ + + /* Erase first sector of active slot */ + printf(" -- Erasing 0x%x bytes at address: 0x%x\r\n", TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE, + TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(slot_number)); + printf(" -- At next boot Signature Verification will fail. Download a new FW to restore FW image !!\r\n\n"); + + /* On this series, the memory corruption is performed by writing again the flash (but not header). + The header is preserved for anti-rollback check. */ + ret = FLASH_If_Write((void *)(TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_ADDRESS(slot_number)), (void *) &pattern, + TEST_PROTECTIONS_CORRUPT_IMAGE_FLASH_SIZE); + + /* This code may not be reached, due to the memory corruption performed. + In this case, the execution will probably trig hard fault exception (while (1)), + then watchdog reset. */ + if (ret == HAL_OK) + { + NVIC_SystemReset(); + } + else + { + printf("-- !! HAL_FLASH_ERROR_CORRUPT_IMAGE: erasing failure ...\r\n\n"); + } +} + +/** + * @brief Display the corruption menu + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_CORRUPT_PrintMenu(void) +{ + printf("\r\n============ Test: CORRUPT ACTIVE IMAGE ============\r\n\n"); + printf(" Corrupt image from SLOT_ACTIVE_1 ---------------------- 1\r\n\n"); + printf(" Previous Menu ----------------------------------------- x\r\n\n"); + printf(" Selection :\r\n\n"); +} + +/** + * @brief Run get firmware info menu. + * @param None + * @retval HAL Status. + */ +static void TEST_PROTECTIONS_CORRUPT_RunMenu(void) +{ + uint8_t key = 0U; + uint32_t exit = 0U; + uint32_t slot_number = 0U; + + /*Print Main Menu message*/ + TEST_PROTECTIONS_CORRUPT_PrintMenu(); + + while (exit == 0U) + { + key = 0U; + slot_number = 0U; + + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload + register */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + + /* Clean the input path */ + COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) + { + case '1' : + slot_number = SLOT_ACTIVE_1; + break; + case 'x' : + exit = 1U; + break; + default: + printf("Invalid Number !\r"); + break; + } + + if (exit != 1U) + { + if (SlotStartAdd[slot_number] == 0U) + { + printf("SLOT_ACTIVE_%d is not configured !\r", slot_number); + } + else + { + TEST_PROTECTIONS_RunCORRUPT(slot_number); + } + + /*Print Main Menu message*/ + TEST_PROTECTIONS_CORRUPT_PrintMenu(); + } + } + } +} + + +/** + * @brief TEST Run TAMPER + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunTAMPER(void) +{ + uint32_t i = 0U; + m_uTamperEvent = 0U; + + printf("\r\n====== Test Protection: TAMPER ========================\r\n\n"); + /* Print instructions*/ + printf(" -- Pull PC13 (CN7.23) to GND \r\n\n"); + printf(" -- -- Note: sometimes it may be enough to put your finger close to PC13 (CN7.23)\r\n\n"); + printf(" -- Should reset if TAMPER is enabled. \r\n\n"); + printf(" Waiting for 10 seconds...\r\n\n") ; + + /* #2 - Wait 10 seconds*/ + while ((i < TEST_PROTECTIONS_TAMPER_DELAY) && (m_uTamperEvent == 0U)) + { + /* If the SecureBoot configured the IWDG, UserApp must reload IWDG counter with value defined in the reload register + */ + WRITE_REG(IWDG->KR, IWDG_KEY_RELOAD); + HAL_Delay(1000U); + i++; + } + if (m_uTamperEvent == 0U) + { + printf("\r\n\n -- Waited 10 seconds, if you have connected TAMPER pin to GND it means TAMPER protection "); + printf("is NOT ENABLED !! \r\n\n"); + } + else + { + printf("\r\n\n -- TAMPER Event detected!!\r\n\n -- System reset requested!!!\r\n\n"); + NVIC_SystemReset(); + } +} + +/** + * @brief TEST Run IWDG + * @param None. + * @retval None. + */ +static void TEST_PROTECTIONS_RunIWDG(void) +{ + printf("\r\n====== Test Protection: IWDG ===========================\r\n\n"); + + /* Wait for TEST_PROTECTIONS_IWDG_DELAY*/ + printf(" -- Waiting %d (ms). Should reset if IWDG is enabled. \r\n\n", TEST_PROTECTIONS_IWDG_DELAY); + + HAL_Delay(TEST_PROTECTIONS_IWDG_DELAY); + + /* No Reset means IWDG was not enabled*/ + printf(" -- !! IWDG protection is NOT ENABLED !!\r\n\n"); +} + +/** + * @} + */ + +/** @defgroup TEST_PROTECTIONS_Callback_Functions Callback Functions + * @{ + */ + +/** + * @brief Implement the Cube_Hal Callback generated on the Tamper IRQ. + * @param None + * @retval None + */ +void CALLBACK_Antitamper(void) +{ + /*Set tamper event variable*/ + m_uTamperEvent = 1U; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app.c new file mode 100644 index 00000000..50a2847b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app.c @@ -0,0 +1,207 @@ +/** + ****************************************************************************** + * @file tkms_app.c + * @author MCD Application Team + * @brief tKMS application examples module. + * This file provides examples of KMS API usages. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" + + +/* Private variables ---------------------------------------------------------*/ +extern void KMS_UPDATE_StartLocalUpdate(void); /* Function to perform Ymodem download of blob image to import */ + +static void tkms_app_print_menu(void) +{ + (void)printf("\r\n======================= tKMS Examples Menu ===========================\r\n\n"); + (void)printf(" (*) Requires execution of 'Import Blob' test (3) prior to execute this one\r\n\n"); + (void)printf(" TKMS - Test All (*) --------------------- 0\r\n\n"); + (void)printf(" TKMS - Tests AES-GCM Embedded key --------------------- 1\r\n\n"); + (void)printf(" TKMS - Tests AES-CBC Embedded key --------------------- 2\r\n\n"); + (void)printf(" TKMS - Import blob --------------------- 3\r\n\n"); + (void)printf(" TKMS - Tests RSA Static key (*) --------------------- 4\r\n\n"); + (void)printf(" TKMS - Tests Derive Static key (*) --------------------- 5\r\n\n"); + (void)printf(" TKMS - Tests key finding --------------------- 6\r\n\n"); + (void)printf(" Exit tKMS Examples Menu --------------------- x\r\n\n"); +} + +void tkms_app_menu(void) +{ + uint8_t key; + uint8_t exit = 0U; + CK_RV ret_status; + uint8_t tests_executed; /* Tests executed count */ + uint8_t tests_success; /* Tests success count */ + uint8_t clear_buffer[128] = "STM32 Key Management Services - Example buffer"; /* Clear text test buffer */ + + /* Initialize tKMS for subsequent usage */ + ret_status = C_Initialize(NULL); + if (ret_status != CKR_OK) + { + (void)printf("tKMS initialization failed\r\n"); + exit = 1; + } + else + { + tkms_app_print_menu(); + } + + while (exit == 0U) /* Till user request to exit this menu, loop on it */ + { + key = 0U; + + INVOKE_SCHEDULE_NEEDS(); + + /* Clean the user input path */ + (void)COM_Flush(); + + /* Receive key */ + if (COM_Receive(&key, 1U, RX_TIMEOUT) == HAL_OK) + { + switch (key) /* User pressed key */ + { + case '0' : + /* + * Execute the whole supported tests in sequence + * For each test: + * - call INVOKE_SCHEDULE_NEEDS to rewarm WDG + * - check results and report test status + * At the end, global result is provided + */ + tests_executed = 0U; + tests_success = 0U; + ret_status = tkms_app_encrypt_decrypt_aes_gcm(sizeof(clear_buffer), clear_buffer); + (void)printf("AES GCM test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_encrypt_decrypt_aes_cbc(sizeof(clear_buffer), clear_buffer); + (void)printf("AES CBC test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_sign_verify_rsa(sizeof(clear_buffer), clear_buffer); + (void)printf("RSA test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_derive_key(sizeof(clear_buffer), clear_buffer); + (void)printf("Derive key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_find(); + (void)printf("Find key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tests_executed++; + tests_success += (ret_status == CKR_OK) ? 1U : 0U; + INVOKE_SCHEDULE_NEEDS(); + /* Report final status */ + if (tests_success == tests_executed) + { + (void)printf("CUMULATIVE RESULT: ALL TESTS PASSED\r\n"); + } + else + { + (void)printf("CUMULATIVE RESULT: %d/%d success\r\n", tests_success, tests_executed); + } + tkms_app_print_menu(); + break; + + /* 1 = TKMS - Tests AES-GCM Embedded key */ + case '1' : + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_encrypt_decrypt_aes_gcm(sizeof(clear_buffer), clear_buffer); + (void)printf("AES GCM test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 2 = Tests AES-CBC Embedded key */ + case '2' : + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_encrypt_decrypt_aes_cbc(sizeof(clear_buffer), clear_buffer); + (void)printf("AES CBC test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 3 = Import Blob */ + case '3': + INVOKE_SCHEDULE_NEEDS(); + KMS_UPDATE_StartLocalUpdate(); + tkms_app_print_menu(); + break; + /* 4 = Tests RSA Static key (requires blob import) */ + case '4' : + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_sign_verify_rsa(sizeof(clear_buffer), clear_buffer); + (void)printf("RSA test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 5 = Tests Key derivation (requires blob import) */ + case '5': + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_derive_key(sizeof(clear_buffer), clear_buffer); + (void)printf("Derive key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + /* 6 = Tests Key finding */ + case '6': + INVOKE_SCHEDULE_NEEDS(); + ret_status = tkms_app_find(); + (void)printf("Find key test %s\r\n", (ret_status == CKR_OK) ? "SUCCESSFUL" : "FAILED"); + tkms_app_print_menu(); + break; + case 'x': + exit = 1; + break; + + default: + (void)printf("Invalid Number !\r"); + tkms_app_print_menu(); + break; + } + } + } + + /* Finalize tKMS since no more in use */ + ret_status = C_Finalize(NULL); + if (ret_status != CKR_OK) + { + (void)printf("tKMS finalization failed\r\n"); + } +} + +/* + * Utilities to format buffer in string for display in traces + */ +void tkms_buff2str(uint8_t *pbuff, uint8_t *pstr, uint32_t length) +{ + uint8_t ascii[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + uint8_t *ptmp = pstr; + uint8_t *ptmp2 = pbuff; + for (uint32_t i = 0UL; i < length; i += 1UL) + { + *ptmp = ascii[*ptmp2 >> 4]; + ptmp++; + *ptmp = ascii[*ptmp2 & 0x0FUL]; + ptmp++; + ptmp2++; + } + *ptmp = 0U; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_derive_key.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_derive_key.c new file mode 100644 index 00000000..6d6e7ebb --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_derive_key.c @@ -0,0 +1,210 @@ +/** + ****************************************************************************** + * @file tkms_app_derive_key.c + * @author MCD Application Team + * @brief tKMS application examples module. + * This file provides examples of KMS API usage to derivate a key + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines -----------------------------------------------------------*/ +#define EC_POINT_MAX_LEN (3U + (2U * 32U)) /* EC Point Max Length : X962 header + DER header + + NIST-P256 *2 - > (0x04|LEN|0x04|X|Y) */ +#define DH_SECRET_X_MAX_LEN (32U) /* DH Secret X Max Length */ + +/* Private structures --------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static uint8_t a_string[1024] = {0}; + + +/** + * @brief Key derivation + * This example is showing how to use key derivation to create + * a specific session key. + * @note + * Key derivation shared information between emitter and receiver + * - Secret derivation Key: stored in KMS under + * KMS_KEY_AES128_DERIVABLE_OBJECT_HANDLE object handle + * - Session key variation: transmitted or calculated by both emitter & receiver + * @param length Length of the clear text for encryption/decryption tests + * @param pClearMessage Clear text for encryption/decryption tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_derive_key(uint32_t length, uint8_t *pClearMessage) +{ + uint8_t encrypted_message[256] __attribute__((aligned(8))) = {0}; + uint8_t decrypted_message[256] __attribute__((aligned(8))) = {0}; + /* Generated key template definition */ + CK_ULONG DeriveKey_template_class = CKO_SECRET_KEY; + CK_ULONG DeriveKey_template_destroyable = CK_TRUE; + CK_ULONG DeriveKey_template_encrypt = CK_TRUE; + CK_ULONG DeriveKey_template_decrypt = CK_TRUE; + CK_ULONG DeriveKey_template_extract = CK_TRUE; + CK_ATTRIBUTE DeriveKey_template[] = + { + {CKA_CLASS, (CK_VOID_PTR) &DeriveKey_template_class, sizeof(CK_ULONG)}, + {CKA_DESTROYABLE, (CK_VOID_PTR) &DeriveKey_template_destroyable, sizeof(CK_ULONG)}, + {CKA_ENCRYPT, (CK_VOID_PTR) &DeriveKey_template_encrypt, sizeof(CK_ULONG)}, + {CKA_DECRYPT, (CK_VOID_PTR) &DeriveKey_template_decrypt, sizeof(CK_ULONG)}, + {CKA_EXTRACTABLE, (CK_VOID_PTR) &DeriveKey_template_extract, sizeof(CK_ULONG)} + }; + /* Template to retrieve generate key value */ + CK_ATTRIBUTE GetKey_template[] = {{CKA_VALUE, (CK_VOID_PTR) &DeriveKey_template_class, 32UL}}; + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + /* Key derivation */ + uint8_t session_variant[32] = "My session variation 0122004578"; + CK_MECHANISM mech = {CKM_AES_ECB_ENCRYPT_DATA, session_variant, 32}; + CK_OBJECT_HANDLE derivedKeyHdle = 0UL; + uint8_t derivedKey[32] = {0}; + /* AES encryption / decryption */ + uint32_t encrypted_length = 0UL; + uint32_t decrypted_length = 0UL; + uint8_t cbc_iv[16] = ">CBC VECTOR "; + CK_MECHANISM aes_cbc_mechanism = { CKM_AES_CBC, (CK_VOID_PTR)cbc_iv, sizeof(cbc_iv) }; + uint8_t tag[16] = {0}; + uint32_t tag_lenth; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Derive key with pass phrase */ + if (rv == CKR_OK) + { + rv = C_DeriveKey(session, &(mech), (CK_OBJECT_HANDLE)KMS_KEY_AES128_DERIVABLE_OBJECT_HANDLE, + &DeriveKey_template[0], sizeof(DeriveKey_template) / sizeof(CK_ATTRIBUTE), &derivedKeyHdle); + } + + /* Get derived key to display */ + if (rv == CKR_OK) + { + GetKey_template[0].pValue = derivedKey; + rv = C_GetAttributeValue(session, derivedKeyHdle, &(GetKey_template[0]), sizeof(GetKey_template) / + sizeof(CK_ATTRIBUTE)); + } + if (rv == CKR_OK) + { + (void)printf("--- Derivating key --------------------------------------------\r\n"); + (void)printf("--- AES ECB\r\n"); + (void)printf("--- Pass phrase [%s]\r\n", session_variant); + tkms_buff2str(derivedKey, a_string, 32); + (void)printf("--- Derived key [%s]\r\n", a_string); + } + + /* Encryption --------------------------------------------------------------*/ + (void)printf("--- Encrypting --------------------------------------------------\r\n"); + (void)printf("--- AES CBC\r\n"); + (void)printf("--- IV [%s]\r\n", cbc_iv); + (void)printf("--- Message [%s]\r\n", pClearMessage); + tkms_buff2str(pClearMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to encrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_EncryptInit(session, &aes_cbc_mechanism, derivedKeyHdle); + } + + /* Encrypt clear message */ + if (rv == CKR_OK) + { + encrypted_length = sizeof(encrypted_message); + rv = C_EncryptUpdate(session, pClearMessage, length, + encrypted_message, &encrypted_length); + } + + /* Finalize message encryption */ + if (rv == CKR_OK) + { + tag_lenth = sizeof(tag); + rv = C_EncryptFinal(session, &tag[0], &tag_lenth); + } + + (void)printf("--- Encrypted ---------------------------------------------------\r\n"); + tkms_buff2str(encrypted_message, a_string, encrypted_length); + (void)printf("--- Message [0x%s]\r\n", a_string); + + /* Decryption --------------------------------------------------------------*/ + + /* Configure session to decrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_DecryptInit(session, &aes_cbc_mechanism, derivedKeyHdle); + } + + /* Decrypt encrypted message */ + if (rv == CKR_OK) + { + decrypted_length = sizeof(decrypted_message); + rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, + decrypted_message, &decrypted_length); + } + + /* Finalize message decryption */ + if (rv == CKR_OK) + { + tag_lenth = sizeof(tag); + rv = C_DecryptFinal(session, &tag[0], &tag_lenth); + } + (void)printf("--- Decrypted ---------------------------------------------------\r\n"); + (void)printf("--- Message [%s]\r\n", decrypted_message); + tkms_buff2str(decrypted_message, a_string, decrypted_length); + (void)printf("--- [0x%s]\r\n", a_string); + + /* Compare decrypted message with clear one */ + if (rv == CKR_OK) + { + if (memcmp(pClearMessage, decrypted_message, length) != 0) + { + (void)printf("XXX Decrypted message differs\r\n"); + rv = CKR_FUNCTION_FAILED; + } + else + { + (void)printf(">>> Decrypted message is same\r\n"); + } + } + + /* Remove key once no more needed */ + if (rv == CKR_OK) + { + rv = C_DestroyObject(session, derivedKeyHdle); + } + + /* Verify key is no more usable */ + if (rv == CKR_OK) + { + if (C_EncryptInit(session, &aes_cbc_mechanism, derivedKeyHdle) == CKR_OK) + { + rv = CKR_FUNCTION_FAILED; + } + } + + /* Close sessions */ + (void)C_CloseSession(session); + + return rv; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c new file mode 100644 index 00000000..5692f717 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c @@ -0,0 +1,293 @@ +/** + ****************************************************************************** + * @file tkms_app_encrypt_decrypt.c + * @author MCD Application Team + * @brief KMS application examples module. + * This file provides examples of KMS API usage to encrypt & decrypt + * messages. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines ---------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static uint8_t a_string[1024] = {0}; +static uint8_t encrypted_message[256] __attribute__((aligned(8))) = {0}; +static uint8_t decrypted_message[256] __attribute__((aligned(8))) = {0}; + +/** + * @brief AES GCM 128 Bits + * This example is showing how to use AES GCM encryption/decryption to + * authenticate and protect a message. + * @note + * Shared information between emitter and receiver + * - Secret encryption/decryption Key: stored in KMS under + * KMS_KEY_AES128_OBJECT_HANDLE object handle + * - Encrypted message: transmitted from emitter to sender + * - Initialization Vector: transmitted from emitter to sender + * - Message Header: transmitted from emitter to sender + * - Authentication Tag: transmitted from emitter to sender + * (calculated during encryption, verified during decryption) + * @param length Length of the clear text for encryption/decryption tests + * @param pClearMessage Clear text for encryption/decryption tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_encrypt_decrypt_aes_gcm(uint32_t length, uint8_t *pClearMessage) +{ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t encrypted_length = 0UL; + uint32_t decrypted_length = 0UL; + uint8_t tag[16] = {0}; /* 128 bits tag size */ + uint32_t tag_lenth = 0UL; + + /* AES GCM Configuration variables */ + uint8_t gcm_iv[12] = ">GCM VECTOR"; + uint8_t gcm_header[16] = ">AES GCM Header"; + /* Prepare GCM mechanism */ + CK_GCM_PARAMS gcm_params = + { + (CK_BYTE *)gcm_iv, + sizeof(gcm_iv), + (CK_BYTE_PTR)gcm_header, + sizeof(gcm_header), + 128 /* Tag length in Bits */ + }; + CK_MECHANISM aes_gcm_mechanism = { CKM_AES_GCM, (CK_VOID_PTR *)(uint32_t) &gcm_params, sizeof(gcm_params) }; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Encryption --------------------------------------------------------------*/ + (void)printf("--- Encrypting --------------------------------------------------\r\n"); + (void)printf("--- AES GCM\r\n"); + (void)printf("--- IV [%s]\r\n", gcm_iv); + (void)printf("--- Header [%s]\r\n", gcm_header); + (void)printf("--- Message [%s]\r\n", pClearMessage); + tkms_buff2str(pClearMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to encrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_EncryptInit(session, &aes_gcm_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES128_OBJECT_HANDLE); + } + + /* Encrypt clear message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + encrypted_length = sizeof(encrypted_message); + rv = C_EncryptUpdate(session, pClearMessage, length, + encrypted_message, &encrypted_length); + } + + /* Finalize message encryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_EncryptFinal(session, &tag[0], &tag_lenth); + } + + (void)printf("--- Encrypted ---------------------------------------------------\r\n"); + tkms_buff2str(encrypted_message, a_string, encrypted_length); + (void)printf("--- Message [0x%s]\r\n", a_string); + tkms_buff2str(tag, a_string, tag_lenth); + (void)printf("--- Tag [0x%s]\r\n", a_string); + + /* Decryption --------------------------------------------------------------*/ + + /* Configure session to decrypt message in AES GCM with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_DecryptInit(session, &aes_gcm_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES128_OBJECT_HANDLE); + } + + /* Decrypt encrypted message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + decrypted_length = sizeof(decrypted_message); + rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, + decrypted_message, &decrypted_length); + } + + /* Finalize message decryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_DecryptFinal(session, &tag[0], &tag_lenth); + } + (void)printf("--- Decrypted ---------------------------------------------------\r\n"); + (void)printf("--- Message [%s]\r\n", decrypted_message); + tkms_buff2str(decrypted_message, a_string, decrypted_length); + (void)printf("--- [0x%s]\r\n", a_string); + + if (rv == CKR_OK) + { + (void)printf(">>> Decrypted message authenticated\r\n"); + } + else + { + (void)printf("XXX Decrypted message not authenticated\r\n"); + } + + /* Compare decrypted message with clear one */ + if (rv == CKR_OK) /* Tag verification done into C_DecryptFinal, thus tag check reflected into rv */ + { + if (memcmp(pClearMessage, decrypted_message, length) != 0) + { + (void)printf("XXX Decrypted message differs\r\n"); + rv = CKR_FUNCTION_FAILED; + } + else + { + (void)printf(">>> Decrypted message is same\r\n"); + } + } + + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + +/** + * @brief AES CBC 256 Bits + * This example is showing how to use AES CBC encryption/decryption to + * protect a message. + * @note + * CBC shared information between emitter and receiver + * - Secret encryption/decryption Key: stored in KMS under + * KMS_KEY_AESC256_OBJECT_HANDLE object handle + * - Encrypted message: transmitted from emitter to sender + * - Initialization Vector: transmitted from emitter to sender + * @param length Length of the clear text for encryption/decryption tests + * @param pClearMessage Clear text for encryption/decryption tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_encrypt_decrypt_aes_cbc(uint32_t length, uint8_t *pClearMessage) +{ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t encrypted_length = 0UL; + uint32_t decrypted_length = 0UL; + uint8_t tag[16] = {0}; + uint32_t tag_lenth; + + /* AES CBC Configuration variables */ + uint8_t cbc_iv[16] = ">CBC VECTOR "; + CK_MECHANISM aes_cbc_mechanism = { CKM_AES_CBC, (CK_VOID_PTR)(uint32_t)cbc_iv, sizeof(cbc_iv) }; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Encryption --------------------------------------------------------------*/ + (void)printf("--- Encrypting --------------------------------------------------\r\n"); + (void)printf("--- AES CBC\r\n"); + (void)printf("--- IV [%s]\r\n", cbc_iv); + (void)printf("--- Message [%s]\r\n", pClearMessage); + tkms_buff2str(pClearMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to encrypt message in AES CBC with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_EncryptInit(session, &aes_cbc_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES256_OBJECT_HANDLE); + } + + /* Encrypt clear message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + encrypted_length = sizeof(encrypted_message); + rv = C_EncryptUpdate(session, pClearMessage, length, + encrypted_message, &encrypted_length); + } + + /* Finalize message encryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_EncryptFinal(session, &tag[0], &tag_lenth); + } + + (void)printf("--- Encrypted ---------------------------------------------------\r\n"); + tkms_buff2str(encrypted_message, a_string, encrypted_length); + (void)printf("--- Message [0x%s]\r\n", a_string); + + /* Decryption --------------------------------------------------------------*/ + + /* Configure session to decrypt message in AES CBC with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_DecryptInit(session, &aes_cbc_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_AES256_OBJECT_HANDLE); + } + + /* Decrypt encrypted message */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + decrypted_length = sizeof(decrypted_message); + rv = C_DecryptUpdate(session, encrypted_message, encrypted_length, + decrypted_message, &decrypted_length); + } + + /* Finalize message decryption */ + if (rv == CKR_OK) + { + /* Set given buffer length */ + tag_lenth = sizeof(tag); + rv = C_DecryptFinal(session, &tag[0], &tag_lenth); /* In case of AES CBC, no tag comparison is done */ + } + (void)printf("--- Decrypted ---------------------------------------------------\r\n"); + (void)printf("--- Message [%s]\r\n", decrypted_message); + tkms_buff2str(decrypted_message, a_string, decrypted_length); + (void)printf("--- [0x%s]\r\n", a_string); + + /* Compare decrypted message with clear one */ + if (rv == CKR_OK) + { + if (memcmp(pClearMessage, decrypted_message, length) != 0) + { + (void)printf("XXX Decrypted message differs\r\n"); + rv = CKR_FUNCTION_FAILED; + } + else + { + (void)printf(">>> Decrypted message is same\r\n"); + } + } + + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_find.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_find.c new file mode 100644 index 00000000..6241319d --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_find.c @@ -0,0 +1,96 @@ +/** + ****************************************************************************** + * @file tkms_app_find.c + * @author MCD Application Team + * @brief KMS application examples module. + * This file provides examples of KMS API usage to find + * objects. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines -----------------------------------------------------------*/ +#define TEST_KEY_AES128 "USERCRYP128" +#define TEST_KEY_AES256 "USERCRYP256" +/* Private variables ---------------------------------------------------------*/ + +/** + * @brief Object search + * This example is showing how to find an object. + * @param None + * @retval CK_RV return value. + */ +CK_RV tkms_app_find(void) +{ + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + CK_ATTRIBUTE object_template; + CK_OBJECT_HANDLE object_handle; + CK_ULONG count; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Fill in the template with the attribute to retrieve the specific key + (CKA_LABEL is used to refer to a specific object) */ + object_template.type = CKA_LABEL; + object_template.pValue = TEST_KEY_AES128; + object_template.ulValueLen = sizeof(TEST_KEY_AES128); + + (void)printf("--- Find Object -----------------------------------------------------\r\n"); + (void)printf("--- Label [%s]\r\n", (uint8_t *)object_template.pValue); + + /* Find Objects Init : template of the object to retrieve is passed to KMS */ + if (rv == CKR_OK) + { + rv = C_FindObjectsInit(session, (CK_ATTRIBUTE_PTR)&object_template, 1); + } + + /* Find Objects : Find object corresponding to the template specified in FindObjectsInit */ + if (rv == CKR_OK) + { + count = 1; + rv = C_FindObjects(session, &object_handle, 1, &count); + } + + /* Find Objects Final: Finalize the operation */ + if (rv == CKR_OK) + { + rv = C_FindObjectsFinal(session); + } + + if (rv == CKR_OK) + { + (void)printf("--- Object Found ------------------------------------------------\r\n"); + (void)printf("--- Object Handle [%d]\r\n", object_handle); + } + else + { + printf("--- Object Not Found --------------------------------------------\r\n"); + } + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_sign_verify.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_sign_verify.c new file mode 100644 index 00000000..c4a0c8aa --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/tkms_app_sign_verify.c @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * @file tkms_app_sign_verify.c + * @author MCD Application Team + * @brief KMS application examples module. + * This file provides examples of KMS API usage to sign & verify + * messages. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tkms.h" +#include "tkms_app.h" +#include "com.h" +#include "common.h" +#include "kms_platf_objects_interface.h" + +/* Private defines -----------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +static uint8_t a_string[1024] = {0}; +static uint8_t signature[2048 / 8] __attribute__((aligned(8))) = {0}; + + +/** + * @brief RSA 1024 Bits + * This example is showing how to use RSA signature to + * authenticate a message. + * @note + * RSA shared information between emitter and receiver + * - Secret signature/verification Key: stored in KMS under + * KMS_KEY_RSA2048_OBJECT_HANDLE object handle + * - Message to authenticate: transmitted from emitter to sender + * - Signature: transmitted from emitter to sender + * (calculated by emitter, verified by receiver) + * @param length Length of the clear text for signature/verification tests + * @param pMessage Clear text for signature/verification tests + * @retval CK_RV return value. + */ +CK_RV tkms_app_sign_verify_rsa(uint32_t length, uint8_t *pMessage) +{ + + CK_RV rv; + CK_SESSION_HANDLE session; + CK_FLAGS session_flags = CKF_SERIAL_SESSION; /* Read ONLY session */ + uint32_t signature_length = 0UL; + + /* Prepare RSA mechanism */ + CK_MECHANISM rsa_mechanism = { CKM_SHA256_RSA_PKCS, (CK_VOID_PTR *) NULL, 0}; + + /* Open session with KMS */ + rv = C_OpenSession(0, session_flags, NULL, 0, &session); + + /* Signature --------------------------------------------------------------*/ + (void)printf("--- Signing -----------------------------------------------------\r\n"); + (void)printf("--- RSA 1024 bits\r\n"); + (void)printf("--- Message [%s]\r\n", pMessage); + tkms_buff2str(pMessage, a_string, length); + (void)printf("--- [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", length); + + /* Configure session to sign message using RSA with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_SignInit(session, &rsa_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_RSA2048_OBJECT_HANDLE); + } + + /* Sign message */ + if (rv == CKR_OK) + { + signature_length = sizeof(signature); + rv = C_Sign(session, pMessage, length, + signature, &signature_length); + } + + (void)printf("--- Signed ------------------------------------------------------\r\n"); + tkms_buff2str(signature, a_string, signature_length); + (void)printf("--- Signature [0x%s]\r\n", a_string); + (void)printf("--- Length [%d]\r\n", signature_length); + + /* Verification ------------------------------------------------------------*/ + + /* Configure session to verify message using RSA with settings included into the mechanism */ + if (rv == CKR_OK) + { + rv = C_VerifyInit(session, &rsa_mechanism, (CK_OBJECT_HANDLE)KMS_KEY_RSA2048_OBJECT_HANDLE); + } + + /* Verify message */ + if (rv == CKR_OK) + { + rv = C_Verify(session, pMessage, length, + signature, signature_length); + } + + if (rv == CKR_OK) + { + (void)printf(">>> Message authenticated\r\n"); + } + else + { + (void)printf("XXX Message not authenticated\r\n"); + } + + /* Close session with KMS */ + (void)C_CloseSession(session); + + return rv; +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/ymodem.c b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/ymodem.c similarity index 100% rename from Projects/NUCLEO-WL55JC/Applications/SBSFU_2_Images_DualCore/2_Images_UserApp_M0Plus/Src/ymodem.c rename to Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/Src/ymodem.c diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/readme.txt b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/readme.txt new file mode 100644 index 00000000..4d3e4b19 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/1_Image_UserApp/readme.txt @@ -0,0 +1,152 @@ +/** + @page 1_Image_UserApp / Firmware Update - User Application Demo + + @verbatim + ******************** (C) COPYRIGHT 2017 STMicroelectronics ******************* + * @file readme.txt + * @brief This application shows a User Application + ****************************************************************************** + * + * Copyright (c) 2017 STMicroelectronics. All rights reserved. + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + @endverbatim + +@par Application Description + +This application demonstrates firmware download capabilities and provides a set of functions to test the active +protections offered by Secure Boot and Secure Engine. +It also demonstrates key management services through basic examples and specific boot +mechanism (firmware update decryption, verification...) +A terminal connected with the board via VCOM is needed to communicate with the board and to select which feature +to demonstrate. + +For more details, refer to UM2262 "Getting started with SBSFU - software expansion for STM32Cube" available from +the STMicroelectronics microcontroller website www.st.com. + +@par Keywords + +Security, KMS, SBSFU + +@par Directory contents + + - 1_Image_UserApp/Src/com.c Communication module file + - 1_Image_UserApp/Src/common.c Common module file + - 1_Image_UserApp/Src/flash_if.c Flash interface file + - 1_Image_UserApp/Src/fw_update_app.c Firmware update application + - 1_Image_UserApp/Src/kms_object_update_app.c KMS Blob update application + - 1_Image_UserApp/Src/main.c Main program + - 1_Image_UserApp/Src/se_user_code.c Call user defined services running in Secure Engine + - 1_Image_UserApp/Src/sfu_app_new_image.c Manage the new firmware image storage and installation + - 1_Image_UserApp/Src/stm32wlxx_it.c Interrupt handlers + - 1_Image_UserApp/Src/system_stm32wlxx.c STM32 system file + - 1_Image_UserApp/Src/test_protections.c Protection test + - 1_Image_UserApp/Src/tkms_app.c tKMS tests + - 1_Image_UserApp/Src/tkms_app_derive_key.c tKMS key derivation tests + - 1_Image_UserApp/Src/tkms_app_encrypt_decrypt.c tKMS encryption/decryption tests + - 1_Image_UserApp/Src/tkms_app_sign_verify.c tKMS signature/verification tests + - 1_Image_UserApp/Src/ymodem.c Ymodem communication module + - 1_Image_UserApp/Inc/com.h Header for com.c file + - 1_Image_UserApp/Inc/common.h Header for common.c file + - 1_Image_UserApp/Inc/flash_if.h Header for flash_if.c file + - 1_Image_UserApp/Inc/fw_update_app.h Header for fw_update_app.c file + - 1_Image_UserApp/Inc/main.h Header for main.c file + - 1_Image_UserApp/Inc/se_user_code.h Header file for se_user_code.c + - 1_Image_UserApp/Inc/sfu_app_new_image.h Header file for sfu_app_new_image.c + - 1_Image_UserApp/Inc/stm32wlxx_hal_conf.h HAL configuration file + - 1_Image_UserApp/Inc/stm32wlxx_it.h Header for stm32wlxx_it.c file + - 1_Image_UserApp/Inc/stm32wlxx_nucleo_conf.h BSP configuration file + - 1_Image_UserApp/Inc/test_protections.h Header for test_protections.c file + - 1_Image_UserApp/Inc/tkms_app.h Header for tkms_app.c file + - 1_Image_UserApp/Inc/ymodem.h Header for ymodem.c file + +@par Hardware and Software environment + + - This example runs on STM32WL55xx devices. + - This example has been tested with NUCLEO-WL55JC RevC board and can be + easily tailored to any other supported device and development board. + - An up-to-date version of ST-LINK firmware is required. Upgrading ST-LINK firmware + is a feature provided by STM32Cube programmer available on www.st.com. + - This example is based on se_interface_application.o module exported by BFU project. + - This example needs a terminal emulator. + - Microsoft Windows has a limitation whereby paths to files and directories cannot + be longer than 256 characters. Paths to files exceeding that limits cause tools (e.g. compilers, + shell scripts) to fail reading from or writing to such files. + As a workaround, it is advised to use the subst.exe command from within a command prompt to set + up a local drive out of an existing directory on the hard drive, such as: + C:\> subst X: \Firmware + +@par IDE postbuild script + +In order to ease the development process, a postbuild script ("postbuild.bat") is integrated in each IDE project. +This postbuild script: + - is generated when compiling the Secure Engine Core project, + - prepares the firmware image of the user application to be installed in the device. + - prepares the new portion of firmware image: part of firmware image which changed vs a reference firmware image. + The reference firmware image is provided to the postbuild script by manually copying the UserApp.bin of the running + application into RefUserApp.bin (in folder 1_Image_UserApp/IDE). + + As an example, once original user application has been built, downloaded and installed, you may create the + RefUserApp.bin, then change UserAppId constant from 'A' to 'B' in source file main.c, then build again the user + application. + At post processing stage, the portion of code containing the UserAppId will be identified as a difference vs + the reference binary file and a PartialUserApp.sfb will be generated in 1_Image_UserApp_M0Plus/Binary folder. + +A known limitation of this integration occurs when you update the firmware version (parameter of postbuild.bat script). +The IDE does not track this update so you need to force the rebuild of the project manually. + +@par How to use it ? + +Refer to BFU readme and follow steps by steps instructions. + +Once executed, this user application gives access to a menu which allows: + 1 - to download a new firmware + 2 - to test protections (WRP, IWDG, TAMPER) + 3 - to demonstrate how to call user defined services running in Secure Engine + 4 - to provide access to multiple images feature (not supported) + 5 - to validate a firmware image at first start-up (not supported) + a - to demonstrate usage of key management services + +1. Pressing 1 allows to download a new firmware. +Send the user encrypted firmware file (.sfb) with Tera Term by using menu "File > Transfer > YMODEM > Send..." +After the download, the system reboots. +The downloaded encrypted firmware is detected, decrypted, installed and executed. + +The downloaded image can be either a complete UserApp.sfb or a PartialUserApp.sfb. +To download a PartialUserApp.sfb, it is mandatory to have previously installed the UserApp.sfb identified as reference +into the device. + +2. Pressing 2 allows to test protections. + + - CORRUPT IMAGE test (#1): causes a signature verification failure at next boot + - WRP test (#2): causes an error trying to erase write protected code + - IWDG test (#3): causes a reset simulating a deadlock by not refreshing the watchdog + - TAMPER test (#4): causes a reset if a tamper event is detected. In order to generate a tamper event, + user has to connect PC13 (CN7.23) to GND (It may be enough to put your finger close to PC13 (CN7.23)). + +3. Pressing 3 allows to call user defined services running in Secure Engine. +As an example, after selecting the firmware image, SE_APP_GetActiveFwInfo service is called in order +to display the information located in the protected area such as version and size. + +4. This menu is dedicated to multiple images feature. +Feature not available as there is only 1 download area configured. + +5. This menu is dedicated to image validation. +Feature available under ENABLE_IMAGE_STATE_HANDLING compilation switch, not available in this example. + +a. Pressing a allows to enter specific key management services test menu. +With this menu, you should be able to try encryption/decryption, signature/verification or key derivation mechanisms. + + +Note1 : There is only 1 active slot configured in this example. +Note2 : for Linux users Minicom can be used but to do so you need to compile the UserApp project with the MINICOM_YMODEM + switch enabled (ymodem.h) + + + *

      © COPYRIGHT STMicroelectronics

      + */ diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_export.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_export.h new file mode 100644 index 00000000..f43d6d6e --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_export.h @@ -0,0 +1,112 @@ +/** + ****************************************************************************** + * @file mapping_export.h + * @author MCD Application Team + * @brief This file contains the definitions exported from mapping linker files. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MAPPING_EXPORT_H +#define MAPPING_EXPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported constants --------------------------------------------------------*/ +extern uint32_t __ICFEDIT_intvec_start__; +#define INTVECT_START ((uint32_t)& __ICFEDIT_intvec_start__) +extern uint32_t __ICFEDIT_SE_Startup_region_ROM_start__; +#define SE_STARTUP_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Startup_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_Code_region_ROM_start__; +#define SE_CODE_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Code_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_Code_region_ROM_end__; +#define SE_CODE_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_Code_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_IF_region_ROM_start__; +#define SE_IF_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_IF_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_IF_region_ROM_end__; +#define SE_IF_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_IF_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_Key_region_ROM_start__; +#define SE_KEY_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_Key_region_ROM_start__) +extern uint32_t __ICFEDIT_SE_Key_region_ROM_end__; +#define SE_KEY_REGION_ROM_END ((uint32_t)& __ICFEDIT_SE_Key_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_CallGate_region_ROM_start__; +#define SE_CALLGATE_REGION_ROM_START ((uint32_t)& __ICFEDIT_SE_CallGate_region_ROM_start__) +extern uint32_t __ICFEDIT_SB_region_ROM_start__; +#define SB_REGION_ROM_START ((uint32_t)& __ICFEDIT_SB_region_ROM_start__) +extern uint32_t __ICFEDIT_SB_region_ROM_end__; +#define SB_REGION_ROM_END ((uint32_t)& __ICFEDIT_SB_region_ROM_end__) +extern uint32_t __ICFEDIT_SE_region_RAM_start__; +#define SE_REGION_RAM_START ((uint32_t)& __ICFEDIT_SE_region_RAM_start__) +extern uint32_t __ICFEDIT_SE_region_RAM_end__ ; +#define SE_REGION_RAM_END ((uint32_t)& __ICFEDIT_SE_region_RAM_end__) +extern uint32_t __ICFEDIT_SB_region_RAM_start__ ; +#define SB_REGION_RAM_START ((uint32_t)& __ICFEDIT_SB_region_RAM_start__) +extern uint32_t __ICFEDIT_SB_region_RAM_end__ ; +#define SB_REGION_RAM_END ((uint32_t)& __ICFEDIT_SB_region_RAM_end__) +extern uint32_t __ICFEDIT_SE_region_RAM_stack_top__; +#define SE_REGION_RAM_STACK_TOP ((uint32_t)& __ICFEDIT_SE_region_RAM_stack_top__) + +extern uint32_t __ICFEDIT_KMS_DataStorage_start__ ; +#define KMS_DATASTORAGE_START ((uint32_t)& __ICFEDIT_KMS_DataStorage_start__) +extern uint32_t __ICFEDIT_KMS_DataStorage_end__ ; +#define KMS_DATASTORAGE_END ((uint32_t)& __ICFEDIT_KMS_DataStorage_end__) + + +#if defined (__ICCARM__) || defined(__GNUC__) +extern uint32_t __ICFEDIT_SLOT_Active_1_header__; +#define SLOT_ACTIVE_1_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_1_header__) +extern uint32_t __ICFEDIT_SLOT_Active_1_start__; +#define SLOT_ACTIVE_1_START ((uint32_t)& __ICFEDIT_SLOT_Active_1_start__) +extern uint32_t __ICFEDIT_SLOT_Active_1_end__; +#define SLOT_ACTIVE_1_END ((uint32_t)& __ICFEDIT_SLOT_Active_1_end__) +extern uint32_t __ICFEDIT_SLOT_Active_2_header__; +#define SLOT_ACTIVE_2_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_2_header__) +extern uint32_t __ICFEDIT_SLOT_Active_2_start__; +#define SLOT_ACTIVE_2_START ((uint32_t)& __ICFEDIT_SLOT_Active_2_start__) +extern uint32_t __ICFEDIT_SLOT_Active_2_end__; +#define SLOT_ACTIVE_2_END ((uint32_t)& __ICFEDIT_SLOT_Active_2_end__) +extern uint32_t __ICFEDIT_SLOT_Active_3_header__; +#define SLOT_ACTIVE_3_HEADER ((uint32_t)& __ICFEDIT_SLOT_Active_3_header__) +extern uint32_t __ICFEDIT_SLOT_Active_3_start__; +#define SLOT_ACTIVE_3_START ((uint32_t)& __ICFEDIT_SLOT_Active_3_start__) +extern uint32_t __ICFEDIT_SLOT_Active_3_end__; +#define SLOT_ACTIVE_3_END ((uint32_t)& __ICFEDIT_SLOT_Active_3_end__) +extern uint32_t __ICFEDIT_SLOT_Dwl_1_start__; +#define SLOT_DWL_1_START ((uint32_t)& __ICFEDIT_SLOT_Dwl_1_start__) +extern uint32_t __ICFEDIT_SLOT_Dwl_1_end__; +#define SLOT_DWL_1_END ((uint32_t)& __ICFEDIT_SLOT_Dwl_1_end__) +extern uint32_t __ICFEDIT_SLOT_Dwl_2_start__; +#define SLOT_DWL_2_START ((uint32_t)& __ICFEDIT_SLOT_Dwl_2_start__) +extern uint32_t __ICFEDIT_SLOT_Dwl_2_end__; +#define SLOT_DWL_2_END ((uint32_t)& __ICFEDIT_SLOT_Dwl_2_end__) +extern uint32_t __ICFEDIT_SLOT_Dwl_3_start__; +#define SLOT_DWL_3_START ((uint32_t)& __ICFEDIT_SLOT_Dwl_3_start__) +extern uint32_t __ICFEDIT_SLOT_Dwl_3_end__; +#define SLOT_DWL_3_END ((uint32_t)& __ICFEDIT_SLOT_Dwl_3_end__) +extern uint32_t __ICFEDIT_SWAP_start__; +#define SWAP_START ((uint32_t)& __ICFEDIT_SWAP_start__) +extern uint32_t __ICFEDIT_SWAP_end__; +#define SWAP_END ((uint32_t)& __ICFEDIT_SWAP_end__) +#endif /* __ICCARM__ || __GNUC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* MAPPING_EXPORT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_fwimg.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_fwimg.icf new file mode 100644 index 00000000..3f9c5724 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_fwimg.icf @@ -0,0 +1,28 @@ +/*###ICF### Set of symbols used in SE and BFU projects ****/ + +/* Slots must be aligned on sector size */ + +/* swap region (4 kbytes) */ +define exported symbol __ICFEDIT_SWAP_start__ = 0x08015000; +define exported symbol __ICFEDIT_SWAP_end__ = 0x08015FFF; + +/* Active slot #1 (84 Kbytes) */ +define exported symbol __ICFEDIT_SLOT_Active_1_start__ = 0x0802B000; +define exported symbol __ICFEDIT_SLOT_Active_1_end__ = 0x0803FFFF; +define exported symbol __ICFEDIT_SLOT_Active_1_header__= __ICFEDIT_SLOT_Active_1_start__; + +/* Dwl slot #1 (84 kbytes) */ +define exported symbol __ICFEDIT_SLOT_Dwl_1_start__ = 0x08016000; +define exported symbol __ICFEDIT_SLOT_Dwl_1_end__ = 0x0802AFFF; + +/* Slots not configured */ +define exported symbol __ICFEDIT_SLOT_Active_2_header__= 0x00000000; +define exported symbol __ICFEDIT_SLOT_Active_2_start__ = 0x00000000; +define exported symbol __ICFEDIT_SLOT_Active_2_end__ = 0x00000000; +define exported symbol __ICFEDIT_SLOT_Active_3_header__= 0x00000000; +define exported symbol __ICFEDIT_SLOT_Active_3_start__ = 0x00000000; +define exported symbol __ICFEDIT_SLOT_Active_3_end__ = 0x00000000; +define exported symbol __ICFEDIT_SLOT_Dwl_2_start__ = 0x00000000; +define exported symbol __ICFEDIT_SLOT_Dwl_2_end__ = 0x00000000; +define exported symbol __ICFEDIT_SLOT_Dwl_3_start__ = 0x00000000; +define exported symbol __ICFEDIT_SLOT_Dwl_3_end__ = 0x00000000; diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_sbsfu.icf b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_sbsfu.icf new file mode 100644 index 00000000..f41ea3ac --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/EWARM/mapping_sbsfu.icf @@ -0,0 +1,63 @@ +/*###ICF### Set of symbols used in SE and BFU projects ****/ + +/******************************************************************************/ +/* ROM section */ +/******************************************************************************/ + +/* Vector table */ +define exported symbol __ICFEDIT_intvec_start__ = 0x08000000; +define exported symbol __ICFEDIT_Vector_size__ = 0x200; + +/* SE Code region */ +define exported symbol __ICFEDIT_SE_Code_region_ROM_start__ = __ICFEDIT_intvec_start__ + __ICFEDIT_Vector_size__; +define exported symbol __ICFEDIT_SE_CallGate_region_ROM_start__ = __ICFEDIT_SE_Code_region_ROM_start__+ 4; +define exported symbol __ICFEDIT_SE_CallGate_Region_ROM_End__ = __ICFEDIT_SE_Code_region_ROM_start__ + 0x1FF; + +/* SE key region */ +define exported symbol __ICFEDIT_SE_Key_region_ROM_start__ = __ICFEDIT_SE_CallGate_Region_ROM_End__ + 1; +define exported symbol __ICFEDIT_SE_Key_region_ROM_end__ = __ICFEDIT_SE_Key_region_ROM_start__ + 0x2FF; + +/* SE Startup */ +define exported symbol __ICFEDIT_SE_Startup_region_ROM_start__ = __ICFEDIT_SE_Key_region_ROM_end__ + 1; +define exported symbol __ICFEDIT_SE_Code_nokey_region_ROM_start__ = __ICFEDIT_SE_Startup_region_ROM_start__ + 0x100; +define exported symbol __ICFEDIT_SE_Code_region_ROM_end__ = __ICFEDIT_SE_Startup_region_ROM_start__ + 0x80FF; + +/* SE IF ROM: used to locate Secure Engine interface code */ +define exported symbol __ICFEDIT_SE_IF_region_ROM_start__ = __ICFEDIT_SE_Code_region_ROM_end__ + 1; +define exported symbol __ICFEDIT_SE_IF_region_ROM_end__ = __ICFEDIT_SE_IF_region_ROM_start__ + 0x7FF; + +/* SBSFU Code region */ +define exported symbol __ICFEDIT_SB_region_ROM_start__ = __ICFEDIT_SE_IF_region_ROM_end__ + 1; +define exported symbol __ICFEDIT_SB_region_ROM_end__ = 0x08012FFF; + +/* KMS Data Storage (NVMS) region */ +/* KMS Data Storage need for 2 images : 4 kbytes * 2 ==> 8 kbytes */ +define exported symbol __ICFEDIT_KMS_DataStorage_start__ = 0x08013000; +define exported symbol __ICFEDIT_KMS_DataStorage_end__ = 0x08014FFF; + +/* ROM regions definition : ordered */ +define region SE_CallGate_ROM_Region = mem:[from __ICFEDIT_SE_CallGate_region_ROM_start__ to __ICFEDIT_SE_CallGate_Region_ROM_End__]; +define region SE_Key_ROM_region = mem:[from __ICFEDIT_SE_Key_region_ROM_start__ to __ICFEDIT_SE_Key_region_ROM_end__]; +define region SE_ROM_region = mem:[from __ICFEDIT_SE_Code_region_ROM_start__ to __ICFEDIT_SE_Code_region_ROM_end__]; +define region SE_CODE_NOKEY_ROM_region = mem:[from __ICFEDIT_SE_Code_nokey_region_ROM_start__ to __ICFEDIT_SE_Code_region_ROM_end__]; +define region SE_IF_ROM_region = mem:[from __ICFEDIT_SE_IF_region_ROM_start__ to __ICFEDIT_SE_IF_region_ROM_end__]; +define region SB_ROM_region = mem:[from __ICFEDIT_SB_region_ROM_start__ to __ICFEDIT_SB_region_ROM_end__]; +define region KMS_DataStorage = mem:[from __ICFEDIT_KMS_DataStorage_start__ to __ICFEDIT_KMS_DataStorage_end__]; + +/******************************************************************************/ +/* RAM section */ +/* */ +/******************************************************************************/ + +/* SE RAM region */ +define exported symbol __ICFEDIT_SE_region_RAM_start__ = 0x20000000; +define exported symbol __ICFEDIT_SE_region_RAM_stack_top__ = 0x20000C00; /* Secure Engine's private stack */ +define exported symbol __ICFEDIT_SE_region_RAM_end__ = 0x200033FF; + +/* SBSFU RAM region */ +define exported symbol __ICFEDIT_SB_region_RAM_start__ = __ICFEDIT_SE_region_RAM_end__ + 1; +define exported symbol __ICFEDIT_SB_region_RAM_end__ = 0x20007FFF; + +/* RAM regions definition */ +define region SE_RAM_region = mem:[from __ICFEDIT_SE_region_RAM_stack_top__ to __ICFEDIT_SE_region_RAM_end__]; +define region SB_RAM_region = mem:[from __ICFEDIT_SB_region_RAM_start__ to __ICFEDIT_SB_region_RAM_end__]; diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/MDK-ARM/mapping_fwimg.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/MDK-ARM/mapping_fwimg.h new file mode 100644 index 00000000..71988d44 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/MDK-ARM/mapping_fwimg.h @@ -0,0 +1,51 @@ +/** + ****************************************************************************** + * @file mapping_fwimg.h + * @author MCD Application Team + * @brief This file contains definitions for firmware images mapping + ****************************************************************************** + * @attention + * + *

      © Copyright(c) 2017 STMicroelectronics International N.V. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MAPPING_FWIMG_H +#define MAPPING_FWIMG_H + +/* Slots must be aligned on 2048 bytes (0x800) */ + +/* swap (4 kbytes) */ +#define SWAP_START 0x08015000 +#define SWAP_END 0x08015FFF + +/* Active slot #1 (84 kbytes) */ +#define SLOT_ACTIVE_1_START 0x0802B000 +#define SLOT_ACTIVE_1_END 0x0803FFFF +#define SLOT_ACTIVE_1_HEADER SLOT_ACTIVE_1_START + +/* Dwl slot #1 (84 kbytes) */ +#define SLOT_DWL_1_START 0x08016000 +#define SLOT_DWL_1_END 0x0802AFFF + +/* Slots not configured */ +#define SLOT_ACTIVE_2_HEADER 0x00000000 +#define SLOT_ACTIVE_2_START 0x00000000 +#define SLOT_ACTIVE_2_END 0x00000000 +#define SLOT_ACTIVE_3_HEADER 0x00000000 +#define SLOT_ACTIVE_3_START 0x00000000 +#define SLOT_ACTIVE_3_END 0x00000000 +#define SLOT_DWL_2_START 0x00000000 +#define SLOT_DWL_2_END 0x00000000 +#define SLOT_DWL_3_START 0x00000000 +#define SLOT_DWL_3_END 0x00000000 + +#endif diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/MDK-ARM/mapping_sbsfu.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/MDK-ARM/mapping_sbsfu.h new file mode 100644 index 00000000..d154b35b --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/MDK-ARM/mapping_sbsfu.h @@ -0,0 +1,86 @@ +/** + ****************************************************************************** + * @file mapping_sbsfu.h + * @author MCD Application Team + * @brief This file contains definitions for SBSFU mapping + ****************************************************************************** + * @attention + * + *

      © Copyright(c) 2017 STMicroelectronics International N.V. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MAPPING_SBSFU_H +#define MAPPING_SBSFU_H + +/*****************************************************************************/ +/* ROM section */ +/*****************************************************************************/ + +/* Vector table */ +#define VECTOR_SIZE 0x200 +#define INTVECT_START 0x08000000 + +/* SE Code region protected by MPU isolation */ +#define SE_CODE_REGION_ROM_START (INTVECT_START + VECTOR_SIZE) +#define SE_CALLGATE_REGION_ROM_START (SE_CODE_REGION_ROM_START + 4) +#define SE_CALLGATE_REGION_ROM_END (SE_CODE_REGION_ROM_START + 0x1FF) + +/* SE Embedded Keys */ +#define SE_KEY_REGION_ROM_START (SE_CALLGATE_REGION_ROM_END + 0x1) +#define SE_KEY_REGION_ROM_END (SE_KEY_REGION_ROM_START + 0x2FF) + +/* SE Startup */ +#define SE_STARTUP_REGION_ROM_START (SE_KEY_REGION_ROM_END + 1) +#define SE_CODE_NOKEY_REGION_ROM_START (SE_STARTUP_REGION_ROM_START + 0x100) +#define SE_CODE_REGION_ROM_END (SE_STARTUP_REGION_ROM_START + 0x80FF) + +/* SE IF ROM: used to locate Secure Engine interface code */ +#define SE_IF_REGION_ROM_START (SE_CODE_REGION_ROM_END + 0x1) +#define SE_IF_REGION_ROM_END (SE_IF_REGION_ROM_START + 0xAFF) + +/* SBSFU Code region */ +#define SB_REGION_ROM_START (SE_IF_REGION_ROM_END + 1) +#define SB_REGION_ROM_END 0x08012FFF + +/* KMS Data Storage (NVMS) region protected area */ +/* KMS Data Storage need for 2 images : 4 kbytes * 2 ==> 8 kbytes */ +#define KMS_DATASTORAGE_START 0x08013000 +#define KMS_DATASTORAGE_END 0x08014FFF + +/* ROM regions size definition */ +#define SE_CALLGATE_REGION_ROM_SIZE (SE_CALLGATE_REGION_ROM_END - SE_CALLGATE_REGION_ROM_START + 0x1) +#define SE_KEY_REGION_ROM_SIZE (SE_KEY_REGION_ROM_END - SE_KEY_REGION_ROM_START + 0x1) +#define SE_ROM_REGION_SIZE (SE_CODE_REGION_ROM_END - SE_CODE_NOKEY_REGION_ROM_START + 0x1) +#define SE_IF_ROM_REGION_SIZE (SE_IF_REGION_ROM_END - SE_IF_REGION_ROM_START + 0x1) +#define SB_ROM_REGION_SIZE (SB_REGION_ROM_END - SB_REGION_ROM_START + 0x1) +#define KMS_DATASTORAGE_SIZE (KMS_DATASTORAGE_END - KMS_DATASTORAGE_START + 0x1) + +/******************************************************************************/ +/* RAM section */ +/* */ +/******************************************************************************/ + +/* SE RAM region */ +#define SE_REGION_RAM_START 0x20000000 +#define SE_REGION_RAM_STACK_TOP 0x20000C00 /* Secure Engine's private stack */ +#define SE_REGION_RAM_END 0x200033FF + +/* SBSFU RAM region */ +#define SB_REGION_RAM_START (SE_REGION_RAM_END + 0x1) +#define SB_REGION_RAM_END 0x20007FFF + +/* RAM regions definition */ +#define SE_RAM_REGION_SIZE (SE_REGION_RAM_END - SE_REGION_RAM_STACK_TOP + 0x1) +#define SB_RAM_REGION_SIZE (SB_REGION_RAM_END - SB_REGION_RAM_START + 0x1) + +#endif + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_export.h b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_export.h new file mode 100644 index 00000000..b7f862f6 --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_export.h @@ -0,0 +1,110 @@ +/** + ****************************************************************************** + * @file mapping_export.h + * @author MCD Application Team + * @brief This file contains the definitions exported from mapping linker files. + ****************************************************************************** + * @attention + * + *

      © Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

      + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MAPPING_EXPORT_H +#define MAPPING_EXPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported constants --------------------------------------------------------*/ +extern uint32_t INTVECT_start; +#define INTVECT_START ((uint32_t)& INTVECT_start) +extern uint32_t SE_Startup_region_ROM_start; +#define SE_STARTUP_REGION_ROM_START ((uint32_t)& SE_Startup_region_ROM_start) +extern uint32_t SE_Code_region_ROM_start; +#define SE_CODE_REGION_ROM_START ((uint32_t)& SE_Code_region_ROM_start) +extern uint32_t SE_Code_region_ROM_end; +#define SE_CODE_REGION_ROM_END ((uint32_t)& SE_Code_region_ROM_end) +extern uint32_t SE_IF_region_ROM_start; +#define SE_IF_REGION_ROM_START ((uint32_t)& SE_IF_region_ROM_start) +extern uint32_t SE_IF_region_ROM_end; +#define SE_IF_REGION_ROM_END ((uint32_t)& SE_IF_region_ROM_end) +extern uint32_t SE_Key_region_ROM_start; +#define SE_KEY_REGION_ROM_START ((uint32_t)& SE_Key_region_ROM_start) +extern uint32_t SE_Key_region_ROM_end; +#define SE_KEY_REGION_ROM_END ((uint32_t)& SE_Key_region_ROM_end) +extern uint32_t SE_CallGate_region_ROM_start; +#define SE_CALLGATE_REGION_ROM_START ((uint32_t)& SE_CallGate_region_ROM_start) +extern uint32_t SB_region_ROM_start; +#define SB_REGION_ROM_START ((uint32_t)& SB_region_ROM_start) +extern uint32_t SB_region_ROM_end; +#define SB_REGION_ROM_END ((uint32_t)& SB_region_ROM_end) +extern uint32_t SE_region_RAM_start; +#define SE_REGION_RAM_START ((uint32_t)& SE_region_RAM_start) +extern uint32_t SE_region_RAM_end; +#define SE_REGION_RAM_END ((uint32_t)& SE_region_RAM_end) +extern uint32_t SB_region_RAM_start; +#define SB_REGION_RAM_START ((uint32_t)& SB_region_RAM_start) +extern uint32_t SB_region_RAM_end; +#define SB_REGION_RAM_END ((uint32_t)& SB_region_RAM_end) +extern uint32_t SE_region_RAM_stack_top; +#define SE_REGION_RAM_STACK_TOP ((uint32_t)& SE_region_RAM_stack_top) + +extern uint32_t KMS_DataStorage_start; +#define KMS_DATASTORAGE_START ((uint32_t)& KMS_DataStorage_start) +extern uint32_t KMS_DataStorage_end; +#define KMS_DATASTORAGE_END ((uint32_t)& KMS_DataStorage_end) + +extern uint32_t SLOT_Active_1_header; +#define SLOT_ACTIVE_1_HEADER ((uint32_t)& SLOT_Active_1_header) +extern uint32_t SLOT_Active_1_start; +#define SLOT_ACTIVE_1_START ((uint32_t)& SLOT_Active_1_start) +extern uint32_t SLOT_Active_1_end; +#define SLOT_ACTIVE_1_END ((uint32_t)& SLOT_Active_1_end) +extern uint32_t SLOT_Active_2_header; +#define SLOT_ACTIVE_2_HEADER ((uint32_t)& SLOT_Active_2_header) +extern uint32_t SLOT_Active_2_start; +#define SLOT_ACTIVE_2_START ((uint32_t)& SLOT_Active_2_start) +extern uint32_t SLOT_Active_2_end; +#define SLOT_ACTIVE_2_END ((uint32_t)& SLOT_Active_2_end) +extern uint32_t SLOT_Active_3_header; +#define SLOT_ACTIVE_3_HEADER ((uint32_t)& SLOT_Active_3_header) +extern uint32_t SLOT_Active_3_start; +#define SLOT_ACTIVE_3_START ((uint32_t)& SLOT_Active_3_start) +extern uint32_t SLOT_Active_3_end; +#define SLOT_ACTIVE_3_END ((uint32_t)& SLOT_Active_3_end) +extern uint32_t SLOT_Dwl_1_start; +#define SLOT_DWL_1_START ((uint32_t)& SLOT_Dwl_1_start) +extern uint32_t SLOT_Dwl_1_end; +#define SLOT_DWL_1_END ((uint32_t)& SLOT_Dwl_1_end) +extern uint32_t SLOT_Dwl_2_start; +#define SLOT_DWL_2_START ((uint32_t)& SLOT_Dwl_2_start) +extern uint32_t SLOT_Dwl_2_end; +#define SLOT_DWL_2_END ((uint32_t)& SLOT_Dwl_2_end) +extern uint32_t SLOT_Dwl_3_start; +#define SLOT_DWL_3_START ((uint32_t)& SLOT_Dwl_3_start) +extern uint32_t SLOT_Dwl_3_end; +#define SLOT_DWL_3_END ((uint32_t)& SLOT_Dwl_3_end) +extern uint32_t SWAP_start; +#define SWAP_START ((uint32_t)& SWAP_start) +extern uint32_t SWAP_end; +#define SWAP_END ((uint32_t)& SWAP_end) + + +#ifdef __cplusplus +} +#endif + +#endif /* MAPPING_EXPORT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_fwimg.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_fwimg.ld new file mode 100644 index 00000000..3c67bd5a --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_fwimg.ld @@ -0,0 +1,31 @@ +/* +** LinkerScript +*/ + +/* Slots must be aligned on sector size */ + +/* Swap sector : 4 kbytes */ +SWAP_start = 0x08015000; +SWAP_end = 0x08015FFF; + +/* Active slot #1 (84 kbytes) */ +SLOT_Active_1_start = 0x0802B000; +SLOT_Active_1_end = 0x0803FFFF; +SLOT_Active_1_header = SLOT_Active_1_start; + +/* Dwl slot #1 : (84 kbytes) */ +SLOT_Dwl_1_start = 0x08016000; +SLOT_Dwl_1_end = 0x0802AFFF; + +/* Slots not configured */ +SLOT_Active_2_header = 0x00000000; +SLOT_Active_2_start = 0x00000000; +SLOT_Active_2_end = 0x00000000; +SLOT_Active_3_header = 0x00000000; +SLOT_Active_3_start = 0x00000000; +SLOT_Active_3_end = 0x00000000; +SLOT_Dwl_2_start = 0x00000000; +SLOT_Dwl_2_end = 0x00000000; +SLOT_Dwl_3_start = 0x00000000; +SLOT_Dwl_3_end = 0x00000000; + diff --git a/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld new file mode 100644 index 00000000..9f8d4aff --- /dev/null +++ b/Projects/NUCLEO-WL55JC/Applications/BFU_2_Slots/Linker_Common/STM32CubeIDE/mapping_sbsfu.ld @@ -0,0 +1,85 @@ +/* +** LinkerScript +*/ + +/******************************************************************************/ +/* ROM section */ +/******************************************************************************/ + +/* Vector table */ +INTVECT_start = 0x08000000; +Vector_size = 0x200; + +/* SE Code region protected by MPU isolation */ +SE_Code_region_ROM_start = INTVECT_start + Vector_size; +SE_CallGate_region_ROM_start = SE_Code_region_ROM_start; /* No need to do +4 as we have dummy bytes in SE_CoreBin .ld file */ +SE_CallGate_region_ROM_end = SE_Code_region_ROM_start + 0xFF; + +/* SE Embedded Keys */ +SE_Key_region_ROM_start = SE_CallGate_region_ROM_end + 0x1; +SE_Key_region_ROM_end = SE_Key_region_ROM_start + 0x2FF; + +/* SE Startup */ +SE_Startup_region_ROM_start = SE_Key_region_ROM_end + 0x1; +SE_Code_NoKey_region_ROM_start = SE_Startup_region_ROM_start + 0x100; +SE_Code_region_ROM_end = SE_Startup_region_ROM_start + 0x80FF; + +/* SE IF ROM */ +SE_IF_region_ROM_start = SE_Code_region_ROM_end + 0x1; +SE_IF_region_ROM_end = SE_IF_region_ROM_start + 0xEFF; + +/* SBSFU Code region */ +SB_region_ROM_start = SE_IF_region_ROM_end + 0x1; +SB_region_ROM_end = 0x08012FFF; + +/* KMS Data Storage (NVMS) region protected area */ +/* KMS Data Storage need for 2 images : 4 kbytes * 2 ==> 8 kbytes */ +KMS_DataStorage_start = 0x08013000; +KMS_DataStorage_end = 0x08014FFF; + +/* ROM regions size definition */ +SE_CallGate_region_ROM_size = SE_CallGate_region_ROM_end - SE_CallGate_region_ROM_start + 0x1; +SE_Key_region_ROM_size = SE_Key_region_ROM_end - SE_Key_region_ROM_start + 0x1; +SE_Startup_region_ROM_size = SE_Code_NoKey_region_ROM_start - SE_Startup_region_ROM_start; +SE_Code_region_ROM_size = SE_Code_region_ROM_end - SE_Code_region_ROM_start + 0x1; +SE_Code_NoKey_region_ROM_size = SE_Code_region_ROM_end - SE_Code_NoKey_region_ROM_start + 0x1; +SE_IF_region_ROM_size = SE_IF_region_ROM_end - SE_IF_region_ROM_start + 0x1; +SB_region_ROM_size = SB_region_ROM_end - SB_region_ROM_start + 0x1; +KMS_DataStorage_size = KMS_DataStorage_end - KMS_DataStorage_start + 0x1; + +/******************************************************************************/ +/* RAM section */ +/* */ +/******************************************************************************/ + +/* SE RAM region */ +SE_region_RAM_start = 0x20000000; +SE_region_RAM_stack_top = 0x20000C00; /* Secure Engine's private stack */ +SE_region_RAM_end = 0x200033FF; + +/* SBSFU RAM region */ +SB_region_RAM_start = SE_region_RAM_end + 0x1; +SB_region_RAM_end = 0x20007FFF; + +/* RAM regions size definition */ +SE_region_RAM_size = SE_region_RAM_end - SE_region_RAM_stack_top + 0x1; +SB_region_RAM_size = SB_region_RAM_end - SB_region_RAM_start + 0x1; + +/******************************************************************************/ +/* RAM/ROM regions */ +/* */ +/******************************************************************************/ + +MEMORY +{ + INTVECT_ROM_region (rx) : ORIGIN = INTVECT_start, LENGTH = Vector_size + SE_CallGate_ROM_region (rx) : ORIGIN = SE_CallGate_region_ROM_start, LENGTH = SE_CallGate_region_ROM_size + SE_Key_region_ROM (rx) : ORIGIN = SE_Key_region_ROM_start, LENGTH = SE_Key_region_ROM_size + SE_Startup_ROM_region (rx) : ORIGIN = SE_Startup_region_ROM_start, LENGTH = SE_Startup_region_ROM_size + SE_ROM_region (rx) : ORIGIN = SE_CallGate_region_ROM_start, LENGTH = SE_Code_region_ROM_size + SE_Code_NoKey_ROM_region (rx) : ORIGIN = SE_Code_NoKey_region_ROM_start, LENGTH = SE_Code_NoKey_region_ROM_size + SE_IF_ROM_region (rx) : ORIGIN = SE_IF_region_ROM_start, LENGTH = SE_IF_region_ROM_size + SB_ROM_region (rx) : ORIGIN = SB_region_ROM_start, LENGTH = SB_region_ROM_size + SE_RAM_region (xrw) : ORIGIN = SE_region_RAM_stack_top, LENGTH = SE_region_RAM_size + SB_RAM_region (xrw) : ORIGIN = SB_region_RAM_start, LENGTH = SB_region_RAM_size +} diff --git a/Projects/NUCLEO-WL55JC/Applications/FatFs/FatFs_uSD_Standalone/STM32CubeIDE/.cproject b/Projects/NUCLEO-WL55JC/Applications/FatFs/FatFs_uSD_Standalone/STM32CubeIDE/.cproject index 4a5389db..21a46a76 100644 --- a/Projects/NUCLEO-WL55JC/Applications/FatFs/FatFs_uSD_Standalone/STM32CubeIDE/.cproject +++ b/Projects/NUCLEO-WL55JC/Applications/FatFs/FatFs_uSD_Standalone/STM32CubeIDE/.cproject @@ -110,7 +110,7 @@

    To run the example, you have to do the following:

    @@ -55,9 +55,9 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    • Open the example using your preferred toolchain.
    • Rebuild all files and load the image into target memory.
    • -
    • Run the example by following the readme.txt instructions.
    • +
    • Run the example by following the readme instructions.
    • - Note: refer to section "Development Toolchains and Compilers" and "Supported Devices and EVAL boards" of the Firmware package release notes to know about the SW/HW environment used for the Firmware development and validation. The correct operation of the provided examples is not guaranteed on some environments, for example when using different compiler or board versions. + Note: refer to section "Development Toolchains and Compilers" and "Supported Devices and EVAL, Nucleo and Discovery boards" of the Firmware package release notes to know about the SW/HW environment used for the Firmware development and validation. The correct operation of the provided examples is not guaranteed on some environments, for example when using different compiler or board versions.
    @@ -793,7 +793,7 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    RTC_Alarm_DualCore

    - This multicore project shows how CM4 uses the Alarm A and CM0 uses Alarm B. + This multicore project shows how CPU1 (CM4) uses the Alarm A and CPU2 (CM0) uses Alarm B. CubeMx @@ -1943,14 +1943,13 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    12 -

    Applications

    -

    BFU_1_Image

    +

    Applications

    +

    BFU_1_Slot

    1_Image_BFU

    -The Boot (B) and Firmware Update (FU) solution allows the update -of the STM32 microcontroller built-in program with new firmware versions, adding -new features and correcting potential issues. The update process is performed in -a secure way to prevent unauthorized updates. +The Boot (B) and Firmware Update (FU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates. X @@ -1973,8 +1972,42 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    1_Image_UserApp

    -This application demonstrates firmware download capabilities and provides a set -of functions to test the active protections offered by Secure Boot and Secure Engine. +This application demonstrates firmware download capabilities and provides a set of functions to test the active +protections offered by Secure Boot and Secure Engine. + + X + + +

    BFU_2_Slots

    +

    1_Image_BFU

    + +The Boot (B) and Firmware Update (FU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates. + + X + + +

    1_Image_KMS_Blob

    + +This application is used to generate Key Management Services Blob binary file to be downloaded +with KMS through the ImportBlob() API. + + X + + +

    1_Image_SECoreBin

    + +This application is used to generate Secure Engine Core binary file to be linked +with Boot & Firmware Update application (BFU). + + X + + +

    1_Image_UserApp

    + +This application demonstrates firmware download capabilities and provides a set of functions to test the active +protections offered by Secure Boot and Secure Engine. X @@ -2121,12 +2154,46 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    LoRaWAN_End_Node_DualCoreFreeRTOS

    This directory contains a set of source files that implements a Dual Core (CM4 / CM0) LoRa application -device sending sensors data to LoRa Network server. +device sending sensors data to LoRa Network server with FreeRTOS Task scheduler on CM4. CubeMx

    LoRaWAN_FUOTA

    +

    1_Image_BFU

    + +The Boot (B) and Firmware Update (FU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates. + + X + + +

    1_Image_KMS_Blob

    + +This application is used to generate Key Management Services Blob binary file to be downloaded +with KMS through the ImportBlob() API. + + X + + +

    1_Image_SECoreBin

    + +This application is used to generate Secure Engine Core binary file to be linked +with Boot & Firmware Update application (BFU). + + X + + +

    LoRaWAN_End_Node

    + +This directory contains a set of source files that implements a LoRa application +device with firmware update over the air download capabilities. + + X + + +

    LoRaWAN_FUOTA_DualCore

    2_Images_KMS_Blob

    This application is used to generate Key Management Services Blob binary file to be downloaded @@ -2137,11 +2204,10 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    2_Images_SBSFU

    -The Secure Boot (SB) and Secure Firmware Update (SFU) solution allows the update -of the STM32 microcontroller built-in program with new firmware versions, adding -new features and correcting potential issues. The update process is performed in -a secure way to prevent unauthorized updates and access to confidential on-device -data such as secret code and firmware encryption key. +The Secure Boot (SB) and Secure Firmware Update (SFU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates and access to confidential on-device data such as secret code and +firmware encryption key. X @@ -2157,12 +2223,12 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    LoRaWAN_End_Node_DualCore

    This directory contains a set of source files that implements a Dual Core (CM4 / CM0) LoRa application -device sending sensors data to LoRa Network server. +device with firmware update over the air download capabilities. X -

    SBSFU_2_Images_DualCore

    +

    LoRaWAN_SBSFU_1_Slot_DualCore

    2_Images_KMS_Blob

    This application is used to generate Key Management Services Blob binary file to be downloaded @@ -2173,11 +2239,45 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    2_Images_SBSFU

    -The Secure Boot (SB) and Secure Firmware Update (SFU) solution allows the update -of the STM32 microcontroller built-in program with new firmware versions, adding -new features and correcting potential issues. The update process is performed in -a secure way to prevent unauthorized updates and access to confidential on-device -data such as secret code and firmware encryption key. +The Secure Boot (SB) and Secure Firmware Update (SFU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates and access to confidential on-device data such as secret code and +firmware encryption key. + + X + + +

    2_Images_SECoreBin

    + +This application is used to generate Secure Engine Core binary file to be linked +with Secure Boot & Secure Firmware Update application (SBSFU). + + X + + +

    LoRaWAN_End_Node_DualCore

    + +This directory contains a set of source files that implements a Dual Core (CM4 / CM0) LoRa application +device with security environment offered by Secure Boot and Secure Engine. + + X + + +

    SBSFU_1_Slot_DualCore

    +

    2_Images_KMS_Blob

    + +This application is used to generate Key Management Services Blob binary file to be downloaded +with KMS through the ImportBlob() API. + + X + + +

    2_Images_SBSFU

    + +The Secure Boot (SB) and Secure Firmware Update (SFU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates and access to confidential on-device data such as secret code and +firmware encryption key. X @@ -2192,8 +2292,50 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    2_Images_UserApp_M0Plus

    -This application demonstrates firmware download capabilities and provides a set -of functions to test the active protections offered by Secure Boot and Secure Engine. +This application demonstrates firmware download capabilities and provides a set of functions to test the active +protections offered by Secure Boot and Secure Engine. + + X + + +

    2_Images_UserApp_M4

    + +This application demonstrates firmware download capabilities. + + X + + +

    SBSFU_2_Slots_DualCore

    +

    2_Images_KMS_Blob

    + +This application is used to generate Key Management Services Blob binary file to be downloaded +with KMS through the ImportBlob() API. + + X + + +

    2_Images_SBSFU

    + +The Secure Boot (SB) and Secure Firmware Update (SFU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates and access to confidential on-device data such as secret code and +firmware encryption key. + + X + + +

    2_Images_SECoreBin

    + +This application is used to generate Secure Engine Core binary file to be linked +with Secure Boot & Secure Firmware Update application (SBSFU). + + X + + +

    2_Images_UserApp_M0Plus

    + +This application demonstrates firmware download capabilities and provides a set of functions to test the active +protections offered by Secure Boot and Secure Engine. X @@ -2226,8 +2368,8 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    Sigfox_PushButton

    -This directory contains a set of source files that implements an example of a -Sigfox object sending temperature - and Batterie Level to a Sigfox Network. +This directory contains a set of source files that implements an example of a +Sigfox object sending temperature and Battery Level to a Sigfox Network. CubeMx @@ -2235,15 +2377,58 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    Sigfox_PushButton_DualCore

    This directory contains a set of source files that implements a Dual Core (CM4 / CM0) Sigfox application -example of a Sigfox object sending temperature - and Batterie Level to a Sigfox Network. +example of a Sigfox object sending temperature and Battery Level to a Sigfox Network. + + CubeMx + + +

    Sigfox_SBSFU_1_Slot_DualCore

    +

    2_Images_KMS_Blob

    + +This application is used to generate Key Management Services Blob binary file to be downloaded +with KMS through the ImportBlob() API. + + X + + +

    2_Images_SBSFU

    + +The Secure Boot (SB) and Secure Firmware Update (SFU) solution allows the update of the STM32 microcontroller built-in +program with new firmware versions, adding new features and correcting potential issues. The update process is performed +in a secure way to prevent unauthorized updates and access to confidential on-device data such as secret code and +firmware encryption key. + + X + + +

    2_Images_SECoreBin

    + +This application is used to generate Secure Engine Core binary file to be linked +with Secure Boot & Secure Firmware Update application (SBSFU). + + X + + +

    Sigfox_PushButton_DualCore

    + +This directory contains a set of source files that implements a Dual Core (CM4 / CM0) Sigfox application +device with security environment offered by Secure Boot and Secure Engine. + + X + + +

    SubGHz_Phy

    +

    SubGHz_Phy_Per

    + +This directory contains a set of source files that implements a PER (Packet Error Rate) tests application +with IBM whitening between one Tx device and one Rx device. CubeMx -

    SubGHz_Phy

    SubGHz_Phy_PingPong

    -This directory contains a set of source files that implements a Ping-Pong application +This directory contains a set of source files that implements a Ping-Pong application between two PingPong Devices. CubeMx @@ -2251,35 +2436,31 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    SubGHz_Phy_PingPong_DualCore

    -This directory contains a set of source files that implements a Dual Core (CM4 / CM0) Ping-Pong application +This directory contains a set of source files that implements a Dual Core (CM4 / CM0) Ping-Pong application between two PingPong Devices. CubeMx - Total number of applications: 38 - 38 + Total number of applications: 60 + 60

    Demonstrations

    LocalNetwork

    LocalNetwork_Concentrator

    -This directory contains a set of source files that implements a Concentrator -sending Beacon to administrate a Network of up to 14 sensors and receives -each connected Sensor's data - -This application is targeting the STM32WLxx Nucleo board embedding the STM32WLxx. +This directory contains a set of source files that implements a Concentrator +sending Beacon to administrate a Network of up to 14 sensors and receives +each connected Sensor's data. X

    LocalNetwork_Sensor

    -This directory contains a set of source files that implements Sensor sending Sensor -data to the demo concentrator - -This application is targeting the STM32WLxx Nucleo board embedding the STM32WLxx. +This directory contains a set of source files that implements Sensor sending Sensor +data to the demo concentrator. X @@ -2288,8 +2469,8 @@

    STM32CubeWL Firmware Examples for STM32WLxx Series

    2 - Total number of projects: 254 - 254 + Total number of projects: 276 + 276 diff --git a/README.md b/README.md index d430e784..76da9f19 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # STM32CubeWL MCU Firmware Package +![latest tag](https://img.shields.io/github/v/tag/STMicroelectronics/STM32CubeWL.svg?color=brightgreen) + **STM32Cube** is an STMicroelectronics original initiative to ease the developers life by reducing efforts, time and cost. **STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series. @@ -30,4 +32,4 @@ Details about the content of this release are available in the release note [her **Caution** : The issues and the pull-requests are **strictly limited** to submit problems or suggestions related to the software delivered in this repository. -**For any other question** related to the product, the hardware performance or characteristics, the tools, the environment, you can submit it to the **ST Community** on the STM32 MCUs related [page](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus). +**For any other question** related to the product, the hardware performance or characteristics, the tools, the environment, you can submit it to the **ST Community** on the STM32 MCUs related [page](https://community.st.com/s/topic/0TO0X000000BSqSWAW/stm32-mcus). diff --git a/Release_Notes.html b/Release_Notes.html index 58c6e38b..a3d36c29 100644 --- a/Release_Notes.html +++ b/Release_Notes.html @@ -21,14 +21,12 @@
    -

    Release Notes for STM32CubeWL Firmware Package

    +

    Release Notes for

    +

    STM32CubeWL Firmware Package

    Copyright © 2020 STMicroelectronics

    -

    License

    -

    This software package is licensed by ST under ST license SLA0048, the “License”; You may not use this package except in compliance with the License. You may obtain a copy of the License at:

    -

    http://www.st.com/SLA0048

    Purpose

    STM32WL series will serve all applications requiring Sub-GHz (LoRaWAN, Sigfox) capabilities in a low-power context with an open dual core architecture offer.

    STM32Cube is an STMicroelectronics original initiative to ease developers life by reducing development efforts, time and cost.

    @@ -44,9 +42,7 @@

    Purpose

    All embedded software utilities come with a full set of examples.

    The STM32Cube firmware solution offers a straightforward API with a modular architecture, making it simple to fine tune custom applications and scalable to fit most requirements.

    -
    -STM32Cube
    STM32Cube
    -
    +

    The HAL (Hardware Abstraction Layer) & LL (Low Layers) drivers provided within this package supports the following STM32WLxx product:

    • STM32WL55xx
    • @@ -62,6 +58,7 @@

      Purpose

    • UM2642 : Description of STM32WL HAL and low-layer drivers.
    • AN5409 : STM32Cube MCU Package examples for STM32WL Series.
    • AN5406 : How to build a LoRa® application with STM32CubeWL.
    • +
    • AN5481 : LoRaWAN® AT commands for STM32CubeWL
    • AN5480 : How to build a Sigfox™ application with STM32CubeWL.
    • UM2767 : Getting started with the SBSFU of STM32CubeWL.
    • AN5556 : Getting started with STM32WL dual core using IAR™ and Keil®.
    • @@ -72,15 +69,57 @@

      Purpose

      Update History

      - +

      Main Changes

      -

      First Official Release

      +

      Maintenance release of STM32CubeWL MCU package

      In the STM32CubeWL MCU Package, examples and applications projects are generated with the STM32CubeMX tool to initialize the system, peripherals and middleware stacks. User can open the provided ioc file in STM32CubeMX to modify the settings, add additional peripherals and/or middleware, to build his final application.

      Contents

        +
      • CMSIS Device updates +
          +
        • Update CMSIS device to include latest corrections
        • +
        • Refer to release notes for further details
        • +
      • +
      • HAL/LL Drivers updates +
          +
        • Update HAL/LL drivers to include latest corrections +
            +
          • Update of ADC, COMP, CORTEX, CRYP, EXTI, GPIO, HSEM, I2C, IRDA, IWDG, LPUART, LPTIM, PWR, RCC, RNG, RTC, SMARTCARD, SMBUS, SPI, SUBGHZ, TIM, UART, USART drivers
          • +
          • Update of HAL SMBUS driver to introduce fast mode and fast mode plus +
              +
            • New extension files: stm32wlxx_hal_smbus_ex.h/.c for new APIs
            • +
          • +
        • +
        • Refer to release notes for further details
        • +
      • +
      • Middlewares updates +
          +
        • Update Security middlewares to include latest corrections and evolutions +
        • +
        • Update RF middlewares to include latest corrections and evolutions +
        • +
      • +
      • Utilities updates +
          +
        • Update on adv_trace to include latest corrections +
        • +
      • Projects updates
          +
        • Update of FW projects following changes in latest version of HAL/LL and Middlewares
        • +
        • New BFU application in 2 Slot configuration (1 download slot associated to 1 execution slot)
        • +
        • New SBSFU application in 1 slot configuration (new image is written directly into the execution slot)
        • +
        • New LoRaWAN_FUOTA_DualCore STM32CubeIDE project
        • +
        • New LoRaWAN_FUOTA Single Core project
        • +
        • New RF Secure projects: LoRaWAN_SBSFU_1_Slot_DualCore and Sigfox_SBSFU_1_Slot_DualCore
        • +
        • New SubGHz_Phy_Per Project. Optionally featuring long packet mode (FSK payload > 255 bytes) on stm32wl revision Y
        • The STM32CubeWL Firmware package comes with a rich set of examples running on STMicroelectronics boards, organized by board and provided with preconfigured projects for the main supported toolchains.
        • The exhaustive list of projects is provided in this table (STM32CubeProjectsList.html).
        • The STM32CubeWL Firmware offers full scope of Examples & Applications targeted, developed using STM32CubeMx & ported on 3 toolchains
        • @@ -91,15 +130,13 @@

          Contents

          Name Version -License Release notes Projects -V1.0.0 -see Projects Release note for details +V1.1.0 release notes @@ -112,7 +149,6 @@

          Components

          Name Version -License Release note @@ -120,25 +156,236 @@

          Components

          Cortex-M CMSIS V5.6.0_cm4 -Apache-2.0 +release notes + + +STM32WL CMSIS +V1.1.0 +release notes + + +STM32WLxx_HAL_Driver +V1.1.0 +release notes + + +STM32WLxx_Nucleo +V1.1.0 +release notes + + + +

          Middlewares

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameVersionRelease note
          FatFSR0.12crelease notes
          ST modified 20191011ST release notes
          FreeRTOSv10.2.1release notes
          ST modified 20200117ST release notes
          LoRaWANV4.4.7 release notes
          V2.3.0 ST release notes
          SubGHz_PhyV1.1.0 release notes
          SigfoxV1.7.0 release notes
          STM32_Key_Management_Servicesv1.1.6 release notes
          STM32_Secure_Enginev2.5.0 release notes
          mbed-cryptoV1.1.0release notes
          ST modified 20191107ST release notes
          +

          Utilities

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameVersionRelease note
          confV1.4.1release notes
          lcdV2.0.1release notes
          FontsV2.0.1release notes
          tiny_lpmV1.3.1release notes
          sequencerV1.5.1release notes
          adv_traceV1.2.0 release notes
          timerV1.1.2release notes
          miscV1.0.2 release notes
          +

          Known Limitations

          +
            +
          • Projects: Few projects not available at CubeMx format (with .ioc) as not eligible (due to CubeMx limitations)
          • +
          +

          Development Toolchains and Compilers

          +
            +
          • IAR Embedded Workbench for ARM (EWARM) toolchain V8.30.1 + Patch EWARM + ST-Link
          • +
          • RealView Microcontroller Development Kit (MDK-ARM) toolchain V5.31 + ST-Link +
              +
            • Support of ARM Compiler 6 (AC-5 like warnings) for HAL/LL/BSP drivers and STMicroelectronics Middleware components
            • +
          • +
          • STM32CubeIDE 1.7.0 + ST-Link
          • +
          +

          Supported Devices and Boards

          +
            +
          • STM32WLE5xx, STM32WLE4xx, STM32WL54xx & STM32WL55xx devices
          • +
          • NUCLEO-WL55JC1 & NUCLEO-WL55JC2 (except Sigfox applications) ecosystem boards - Nucleo kit RevC (MB1389-HIGHBAND-E02 or MB1389-LOWBAND-E02)
          • +
          +

          Backward Compatibility

          +

          Not applicable

          +

          Dependencies

          +
            +
          • STM32CubeMX 6.3.0
          • +
          +
      +
      +
      + +
      +

      Main Changes

      +

      First Official Release

      +

      In the STM32CubeWL MCU Package, examples and applications projects are generated with the STM32CubeMX tool to initialize the system, peripherals and middleware stacks. User can open the provided ioc file in STM32CubeMX to modify the settings, add additional peripherals and/or middleware, to build his final application.

      +

      Contents

      +
        +
      • Projects updates +
          +
        • The STM32CubeWL Firmware package comes with a rich set of examples running on STMicroelectronics boards, organized by board and provided with preconfigured projects for the main supported toolchains.
        • +
        • The exhaustive list of projects is provided in this table (STM32CubeProjectsList.html).
        • +
        • The STM32CubeWL Firmware offers full scope of Examples & Applications targeted, developed using STM32CubeMx & ported on 3 toolchains
        • +
      • +
      + + + + + + + + + + + + + + + +
      NameVersionRelease notes
      ProjectsV1.0.0release notes
      +

      Components

      +

      The components flagged by “” have changed since the previous release. “” are new.

      +

      Drivers

      + + + + + + + + + + + + - - - @@ -149,7 +396,6 @@

      Components

      - @@ -157,73 +403,61 @@

      Components

      - - - - - - - + - - - - - - @@ -234,7 +468,6 @@

      Components

      - @@ -242,72 +475,64 @@

      Components

      - - - - - - - -
      NameVersionRelease note
      Cortex-M CMSISV5.6.0_cm4 release notes
      STM32WL CMSIS V1.0.0Apache-2.0 release notes
      STM32WLxx_HAL_Driver V1.0.0BSD-3-Clause release notes
      STM32WLxx_Nucleo V1.0.0BSD-3-Clause release notes
      Name VersionLicense Release note
      FatFS R0.12cBSD-3-Clause release notes
      ST modified 20191011 ST release notes
      FreeRTOS V10.2.1MIT-License release notes
      ST modified 20200117 ST release notes
      LoRaWAN V4.4.4BSD-3-Clause release notes
      V2.2.1ST release notesST release notes](Middlewares/Third_Party/LoRaWAN/st_readme.txt)
      SubGHz_Phy V1.0.0BSD-3-Clause release notes
      Sigfox V1.6.1SLA0044 - Sigfox Specific Terms release notes
      STM32_Key_Management_Services v1.1.5SLA0044 release notes
      STM32_Secure_Engine v2.4.1SLA0044 release notes
      mbed-crypto V1.1.0Apache-2.0 release notes
      ST modified 20191107 ST release notes
      Name VersionLicense Release note
      conf V1.4.1BSD-3-Clause release notes
      lcd V2.0.1BSD-3-Clause release notes
      Fonts V2.0.1BSD-3-Clause release notes
      tiny_lpm V1.3.1BSD-3-Clause release notes
      sequencer V1.5.1BSD-3-Clause release notes
      adv_trace V1.0.5BSD-3-Clause release notes
      timer V1.1.2BSD-3-Clause release notes
      misc V1.0.0BSD-3-Clause release notes
      -

      Known Limitations

      +

      Known Limitations

      • Projects: Few projects not available at CubeMx format (with .ioc) as not eligible (due to CubeMx limitations)
      • Projects: LoRaWAN_FUOTA application not ported on CubeIDE
      -

      Development Toolchains and Compilers

      +

      Development Toolchains and Compilers

      • IAR Embedded Workbench for ARM (EWARM) toolchain V8.30.1 + Patch EWARM + ST-Link
      • RealView Microcontroller Development Kit (MDK-ARM) toolchain V5.28 + Patch MDK-ARM + ST-Link
      • STM32CubeIDE 1.5.0 + ST-Link
      -

      Supported Devices and Boards

      +

      Supported Devices and Boards

      • STM32WLE5xx, STM32WLE4xx, STM32WL54xx & STM32WL55xx devices
      • NUCLEO-WL55JC1 & NUCLEO-WL55JC2 (except Sigfox applications) ecosystem boards - Nucleo kit RevC (MB1389-HIGHBAND-C01 or MB1389-LOWBAND-C01)
      -

      Backward Compatibility

      +

      Backward Compatibility

      Not applicable

      -

      Dependencies

      +

      Dependencies

      • STM32CubeMX 6.1.0
      diff --git a/Utilities/PC_Software/EWARMv8_STM32WLxx_Support_V4.7.zip b/Utilities/PC_Software/EWARMv8_STM32WLxx_Support_V4.7.zip new file mode 100644 index 00000000..bf01d34d Binary files /dev/null and b/Utilities/PC_Software/EWARMv8_STM32WLxx_Support_V4.7.zip differ diff --git a/Utilities/PC_Software/EWARMv8_STM32WLxx_V4.6.zip b/Utilities/PC_Software/EWARMv8_STM32WLxx_V4.6.zip deleted file mode 100644 index 5d8f0c22..00000000 Binary files a/Utilities/PC_Software/EWARMv8_STM32WLxx_V4.6.zip and /dev/null differ diff --git a/Utilities/PC_Software/Keil.STM32WLxx_DFP.1.0.7.zip b/Utilities/PC_Software/Keil.STM32WLxx_DFP.1.0.7.zip deleted file mode 100644 index 727fba0d..00000000 Binary files a/Utilities/PC_Software/Keil.STM32WLxx_DFP.1.0.7.zip and /dev/null differ diff --git a/Utilities/misc/Release_notes.html b/Utilities/misc/Release_notes.html index 657398d2..d034f6b0 100644 --- a/Utilities/misc/Release_notes.html +++ b/Utilities/misc/Release_notes.html @@ -5,59 +5,45 @@ Release Notes for STM32 miscellaneous utilities - - + +
      -
      -
      -

      Release Notes for STM32 miscellaneous utilities

      -

      Copyright © 2020 STMicroelectronics
      +

      Release Notes for STM32 miscellaneous utilities

      +

      Copyright © 2021 STMicroelectronics

      - +
      -
      -

      License

      This software component is licensed by ST under BSD 3-Clause license, the “License”; You may not use this file except in compliance with the License. You may obtain a copy of the License at:

      https://opensource.org/licenses/BSD-3-Clause

      Purpose

      The source code delivered is a utility to help managing miscellaneous utilities within an embedded application: memory, system time and vsnprintf.

      -
      -

      Update History

      +
      +

      Update History

      - +

      Main Changes

      -

      release V1.0.0

      +

      release V1.0.2

      Contents

      - - - - - - - - - - - - - - -
      Headline
      First release
      +

      Update release note format

      known limitations

      Development Toolchains and Compilers

      Supported Devices and boards

      @@ -65,9 +51,36 @@

      backward compatibility

      Dependencies

      +
      + +
      +

      Main Changes

      +

      release V1.0.1

      +

      Contents

      +

      add empty line at the end of stm32_mem.h

      +

      known limitations

      +

      Development Toolchains and Compilers

      +

      Supported Devices and boards

      +

      backward compatibility

      +

      Dependencies

      +
      +
      +
      + +
      +

      Main Changes

      +

      release V1.0.0

      +

      Contents

      +

      First release

      +

      known limitations

      +

      Development Toolchains and Compilers

      +

      Supported Devices and boards

      +

      backward compatibility

      +

      Dependencies

      +
      +
      -

      :::