Skip to content

Commit fd6ca96

Browse files
ota: Add OTA orchestrator
Add an OTA orchestrator as a helper within the applications/ directory. The OTA orchestrator uses functionality from the Jobs and MQTT File Streaming libraries to enable OTA updates. In addition, update the keyword detection CMakeLists.txt to allow this example to use the new modular OTA. Signed-off-by: Chuyue Luo <[email protected]>
1 parent 25b1075 commit fd6ca96

File tree

15 files changed

+2179
-0
lines changed

15 files changed

+2179
-0
lines changed

.github/.cSpellWords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ coef
3939
compatibil
4040
coremqtt
4141
COSE
42+
coverity
4243
CLRF
4344
Cqqpk
4445
CSRS
@@ -147,6 +148,7 @@ Merkle
147148
Mfcc
148149
MFCC
149150
MFLN
151+
MISRA
150152
mlek
151153
mqtt
152154
mqttconfig

applications/helpers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_subdirectory(device_advisor)
77
add_subdirectory(events)
88
add_subdirectory(hdlcd)
99
add_subdirectory(logging)
10+
add_subdirectory(ota_orchestrator)
1011
add_subdirectory(provisioning)
1112
# sntp helper library depends on FreeRTOS-Plus-TCP connectivity stack as it
1213
# includes `FreeRTOS_IP.h` header file in one of its source files (sntp_client_task.c),
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2024 Arm Limited and/or its affiliates
2+
3+
# SPDX-License-Identifier: MIT
4+
5+
if(BUILD_TESTING AND NOT CMAKE_CROSSCOMPILING)
6+
# Left empty for future mocks.
7+
else()
8+
add_library(ota-update
9+
src/mqtt_helpers.c
10+
src/ota_orchestrator_helpers.c
11+
src/ota_os_freertos.c
12+
src/ota_orchestrator.c
13+
)
14+
15+
target_include_directories(ota-update
16+
PUBLIC
17+
inc/
18+
)
19+
20+
target_link_libraries(ota-update
21+
jobs-for-aws-iot-embedded-sdk
22+
aws-iot-core-mqtt-file-streams-embedded-c
23+
freertos_kernel
24+
corejson
25+
coremqtt
26+
coremqtt-agent
27+
tinycbor
28+
freertos-ota-pal-psa
29+
helpers-events
30+
backoff-algorithm
31+
crt-helpers
32+
)
33+
endif()
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* Copyright 2023-2024 Arm Limited and/or its affiliates
2+
3+
* SPDX-License-Identifier: MIT
4+
*/
5+
6+
#ifndef MQTT_HELPERS_H
7+
#define MQTT_HELPERS_H
8+
9+
/* Standard includes. */
10+
#include <stdlib.h>
11+
#include <stdint.h>
12+
13+
/**
14+
* @ingroup ota_enum_types
15+
* @brief The OTA MQTT interface return status.
16+
*/
17+
typedef enum OtaMqttStatus
18+
{
19+
OtaMqttSuccess = 0, /*!< @brief OTA MQTT interface success. */
20+
OtaMqttPublishFailed = 0xa0, /*!< @brief Attempt to publish a MQTT message failed. */
21+
OtaMqttSubscribeFailed, /*!< @brief Failed to subscribe to a topic. */
22+
OtaMqttUnsubscribeFailed /*!< @brief Failed to unsubscribe from a topic. */
23+
} OtaMqttStatus_t;
24+
25+
/**
26+
* @brief Subscribe to a specified topic.
27+
*
28+
* Precondition: pTopicFilter is not null.
29+
*
30+
* @param[in] pTopicFilter The topic filter to subscribe to.
31+
* @param[in] topicFilterLength Length of the topic filter.
32+
* @param[in] ucQoS Quality of Service (QoS), the level of reliability for
33+
* message delivery. Can be 0, 1 or 2.
34+
*
35+
* @return OtaMqttSuccess if the subscribe completed successfully, otherwise
36+
* OtaMqttSubscribeFailed.
37+
*/
38+
OtaMqttStatus_t prvMQTTSubscribe( const char * pTopicFilter,
39+
uint16_t topicFilterLength,
40+
uint8_t ucQoS );
41+
42+
/**
43+
* @brief Publish a message to a specified topic.
44+
* *
45+
* @param[in] pacTopic The topic that the message should be published to.
46+
* @param[in] topicLen Length of the topic.
47+
* @param[in] pMsg The message to be published.
48+
* @param[in] msgSize Size of the message.
49+
* @param[in] ucQoS Quality of Service (QoS), the level of reliability for
50+
* message delivery. Can be 0, 1 or 2.
51+
*
52+
* @return OtaMqttSuccess if the subscribe completed successfully, otherwise
53+
* OtaMqttSubscribeFailed.
54+
*/
55+
OtaMqttStatus_t prvMQTTPublish( const char * const pacTopic,
56+
uint16_t topicLen,
57+
const char * pMsg,
58+
uint32_t msgSize,
59+
uint8_t ucQoS );
60+
61+
/**
62+
* @brief Unsubscribe from a specified topic.
63+
*
64+
* Precondition: pTopicFilter is not null.
65+
*
66+
* @param[in] pTopicFilter The topic filter to unsubscribe from.
67+
* @param[in] topicFilterLength Length of the topic filter.
68+
* @param[in] ucQoS Quality of Service (QoS), the level of reliability for
69+
* message delivery. Can be 0, 1 or 2.
70+
*
71+
* @return OtaMqttSuccess if the unsubscribe completed successfully, otherwise
72+
* OtaMqttSubscribeFailed.
73+
*/
74+
OtaMqttStatus_t prvMQTTUnsubscribe( const char * pTopicFilter,
75+
uint16_t topicFilterLength,
76+
uint8_t ucQoS );
77+
78+
#endif /* MQTT_HELPERS_H */
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* AWS IoT Over-the-air Update v3.4.0
3+
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* Copyright 2024 Arm Limited and/or its affiliates
5+
6+
*
7+
* SPDX-License-Identifier: MIT
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
10+
* this software and associated documentation files (the "Software"), to deal in
11+
* the Software without restriction, including without limitation the rights to
12+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
13+
* the Software, and to permit persons to whom the Software is furnished to do so,
14+
* subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in all
17+
* copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
21+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25+
*/
26+
27+
/**
28+
* @file ota_appversion32.h
29+
* @brief Structure to represent the application build version.
30+
*/
31+
32+
#ifndef IOT_APPVERSION32_H
33+
#define IOT_APPVERSION32_H
34+
35+
/* *INDENT-OFF* */
36+
#ifdef __cplusplus
37+
extern "C" {
38+
#endif
39+
/* *INDENT-ON* */
40+
41+
/* Standard includes. */
42+
#include <stdint.h>
43+
44+
/**
45+
* @ingroup ota_struct_types
46+
* @brief Application version structure.
47+
*
48+
*/
49+
typedef struct
50+
{
51+
/* MISRA Ref 19.2.1 [Unions] */
52+
/* More details at: https://github.com/aws/ota-for-aws-iot-embedded-sdk/blob/main/MISRA.md#rule-192 */
53+
/* coverity[misra_c_2012_rule_19_2_violation] */
54+
union
55+
{
56+
#if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN )
57+
struct version
58+
{
59+
uint16_t build; /*!< @brief Build of the firmware (Z in firmware version Z.Y.X). */
60+
uint8_t minor; /*!< @brief Minor version number of the firmware (Y in firmware version Z.Y.X). */
61+
62+
uint8_t major; /*!< @brief Major version number of the firmware (X in firmware version Z.Y.X). */
63+
} x; /*!< @brief Version number of the firmware. */
64+
#elif ( defined( __BYTE_ORDER__ ) && defined( __ORDER_BIG_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) || ( __big_endian__ == 1 ) || ( __BYTE_ORDER == __BIG_ENDIAN )
65+
struct version
66+
{
67+
uint8_t major; /*!< @brief Major version number of the firmware (X in firmware version X.Y.Z). */
68+
uint8_t minor; /*!< @brief Minor version number of the firmware (Y in firmware version X.Y.Z). */
69+
70+
uint16_t build; /*!< @brief Build of the firmware (Z in firmware version X.Y.Z). */
71+
} x; /*!< @brief Version number of the firmware. */
72+
#else /* if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN ) */
73+
#error "Unable to determine byte order!"
74+
#endif /* if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN ) */
75+
uint32_t unsignedVersion32;
76+
int32_t signedVersion32;
77+
} u; /*!< @brief Version based on configuration in big endian or little endian. */
78+
} AppVersion32_t;
79+
80+
extern AppVersion32_t appFirmwareVersion; /*!< @brief Making the version number available globally through external linkage. */
81+
82+
/* *INDENT-OFF* */
83+
#ifdef __cplusplus
84+
}
85+
#endif
86+
/* *INDENT-ON* */
87+
88+
#endif /* ifndef IOT_APPVERSION32_H */
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
3+
* Copyright 2024 Arm Limited and/or its affiliates
4+
5+
*
6+
* SPDX-License-Identifier: MIT
7+
* Licensed under the MIT License. See the LICENSE accompanying this file
8+
* for the specific language governing permissions and limitations under
9+
* the License.
10+
*/
11+
12+
#ifndef OTA_ORCHESTRATOR_HELPERS_H
13+
#define OTA_ORCHESTRATOR_HELPERS_H
14+
15+
/* Standard includes. */
16+
#include <stdbool.h>
17+
#include <stdint.h>
18+
19+
#include "job_parser.h"
20+
21+
/**
22+
* @brief Convert a job document signature into DER format.
23+
*
24+
* @param[in] dest The destination buffer to be populated with the decoded
25+
* signature
26+
* @param[in] destLength Length of the dest buffer.
27+
* @param[in] jobFields Pointer to the structure holding the job document
28+
* parameters, which will be populated with the decoded signature.
29+
*
30+
* @return true if the signature was successfully decoded, otherwise false.
31+
*/
32+
bool convertSignatureToDER( uint8_t * dest,
33+
size_t destLength,
34+
AfrOtaJobDocumentFields_t * jobFields );
35+
36+
/**
37+
* @brief Parse the job document to extract the parameters needed to download
38+
* the new firmware.
39+
*
40+
* @param[in] message The jobs message received from AWS IoT core.
41+
* @param[in] messageLength Length of the message.
42+
* @param[in] jobFields Pointer to the structure to be populated with the job
43+
* document fields.
44+
*
45+
* @return true if all files processed, otherwise false.
46+
*/
47+
bool jobDocumentParser( char * message,
48+
size_t messageLength,
49+
AfrOtaJobDocumentFields_t * jobFields );
50+
51+
#endif /* OTA_ORCHESTRATOR_HELPERS_H */
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
3+
* Copyright 2024 Arm Limited and/or its affiliates
4+
5+
*
6+
* SPDX-License-Identifier: MIT
7+
* Licensed under the MIT License. See the LICENSE accompanying this file
8+
* for the specific language governing permissions and limitations under
9+
* the License.
10+
*/
11+
12+
/**
13+
* @file ota_os_freertos.h
14+
* @brief Function declarations for the example OTA OS Functional interface for
15+
* FreeRTOS.
16+
*/
17+
18+
#ifndef _OTA_OS_FREERTOS_H_
19+
#define _OTA_OS_FREERTOS_H_
20+
21+
/* Standard library includes. */
22+
#include <stdbool.h>
23+
#include <stdint.h>
24+
#include <stdio.h>
25+
#include <string.h>
26+
27+
/**
28+
* @ingroup ota_enum_types
29+
* @brief The OTA OS interface return status.
30+
*/
31+
typedef enum OtaOsStatus
32+
{
33+
OtaOsSuccess = 0, /*!< @brief OTA OS interface success. */
34+
OtaOsEventQueueCreateFailed = 0x80U, /*!< @brief Failed to create the event
35+
* queue. */
36+
OtaOsEventQueueSendFailed, /*!< @brief Posting event message to the event
37+
* queue failed. */
38+
OtaOsEventQueueReceiveFailed, /*!< @brief Failed to receive from the event
39+
* queue. */
40+
OtaOsEventQueueDeleteFailed, /*!< @brief Failed to delete the event queue.
41+
*/
42+
} OtaOsStatus_t;
43+
44+
/**
45+
* @brief Initialize the OTA events.
46+
*
47+
* This function initializes the OTA events mechanism for freeRTOS platforms.
48+
*
49+
* @param[pEventCtx] Pointer to the OTA event context.
50+
*
51+
* @return OtaOsStatus_t, OtaOsSuccess if success , other error
52+
* code on failure.
53+
*/
54+
OtaOsStatus_t OtaInitEvent_FreeRTOS();
55+
56+
/**
57+
* @brief Sends an OTA event.
58+
*
59+
* This function sends an event to OTA library event handler on FreeRTOS
60+
* platforms.
61+
*
62+
* @param[pEventCtx] Pointer to the OTA event context.
63+
*
64+
* @param[pEventMsg] Event to be sent to the OTA handler.
65+
*
66+
* @param[timeout] The maximum amount of time (msec) the task should
67+
* block.
68+
*
69+
* @return OtaOsStatus_t, OtaOsSuccess if success , other error
70+
* code on failure.
71+
*/
72+
OtaOsStatus_t OtaSendEvent_FreeRTOS( const void * pEventMsg );
73+
74+
/**
75+
* @brief Receive an OTA event.
76+
*
77+
* This function receives next event from the pending OTA events on FreeRTOS
78+
* platforms.
79+
*
80+
* @param[pEventCtx] Pointer to the OTA event context.
81+
*
82+
* @param[pEventMsg] Pointer to store message.
83+
*
84+
* @param[timeout] The maximum amount of time the task should block.
85+
*
86+
* @return OtaOsStatus_t, OtaOsSuccess if success , other error
87+
* code on failure.
88+
*/
89+
OtaOsStatus_t OtaReceiveEvent_FreeRTOS( void * pEventMsg );
90+
91+
/**
92+
* @brief Deinitialize the OTA Events mechanism.
93+
*
94+
* This function deinitialize the OTA events mechanism and frees any resources
95+
* used on FreeRTOS platforms.
96+
*
97+
* @param[pEventCtx] Pointer to the OTA event context.
98+
*
99+
* @return OtaOsStatus_t, OtaOsSuccess if success , other error
100+
* code on failure.
101+
*/
102+
void OtaDeinitEvent_FreeRTOS();
103+
104+
#endif /* ifndef _OTA_OS_FREERTOS_H_ */

0 commit comments

Comments
 (0)