The library provides support for performing over-the-air (OTA) updates on the application code that runs on various devices, including PSoC™ 6 Connectivity Devices, 20829 (CYW920829M2EVK-02) Devices, 89829 (CYW989829M2EVB-01) Devices, XMC7000 (KIT_XMC72_EVK) Devices, and CYW955913SDCM2WLIPA (CYW955913EVK-01) Devices, which can be connected via Wi-Fi, Bluetooth®, or Ethernet.
For simplification, this document may refer to an MQTT Broker or an HTTP Server as "server".
The library provides a number of combinations to get the OTA image:
1. Over Bluetooth®
- We use a Push model with Bluetooth®. A Peer application running on a laptop or phone will connect and push an update to the Device.
2. Over Wi-Fi or Ethernet(MQTT/HTTP)
- MQTT and HTTP use a Pull model. There are two flows for getting the OTA image(JOB flow and Direct flow).
2.1 Pull Model using a JOB flow:
- Step 1: Get Job:
- The OTA Agent downloads a JSON "Job" document (default name "ota_update.json").
- The Job document has information about an update that is available, including its location.
- Step 2: Get Data:
- The OTA Agent will download the OTA image and writes it to the configured upgrade slot using registered "upgrade image handling storage callback APIs".
2.2 Pull Model using a Direct flow:
- Step 1: Get Data:
- The OTA Agent will download the OTA image from predefined location and writes it to the configured upgrade slot using registered "upgrade image handling storage callback APIs".
- Choose direct flow by setting the use_get_job_flow field in cy_ota_network_params_t to CY_OTA_DIRECT_FLOW when calling cy_ota_agent_start().
On the next reboot, Bootloader will take care of booting the new version of the application from the configured upgrade slot.
The ModusToolbox OTA code examples import this OTA library automatically.
Features and Functionality
This library utilizes MQTT or HTTPS and TLS, or Bluetooth® to securely connect to and download an update for the users application. Server info, credentials, and other parameters are passed into cy_ota_agent_start().
Other features:
- MQTT and HTTP
- Configuration to adjust multiple timing values to customize how often to check for updates, and other parameters for the MQTT Broker connection.
- Runs in a separate background thread, only connecting to the server based on the parameters passed to cy_ota_agent_start().
- Provides a callback mechanism to report stages of connect, download percentage, and errors.
- Once the application starts the OTA Agent, the OTA Agent will contact the server at the defined intervals to see if there is an update available.
- Upon receiving the upgrade image, OTA Agent gives a callback to the application for handling the upgrade image.
- Bluetooth®
- Runs in a separate thread with callbacks to the users application to handle the connection messages and download data.
- When Bluetooth® is enabled in the compile flags, the Bluetooth® server will start automatically.
Integration Notes
Before enabling OTA in an application, the user must choose a suitable bootloader and program it on the chosen platform(s). The required build environment for creating BOOT and UPGRADE images should be set up. To add the required bootloader support at the application level itself, the OTA update library implements a callback mechanism and offloads handling of upgrade images including flash operations to application. The application must implement these storage operation callbacks defined in ota-update/<version>/include/cy_ota_api.h to handle upgrade image based on bootloader choosen and must register callbacks during OTA agent start by giving a parameter of type 'cy_ota_storage_interface_t' in 'cy_ota_agent_start()'.
A pre-defined configuration file has been bundled with this library and the user is expected to:
- Copy the cy_ota_config.h file from the ota-update/<version>/configs directory to the top-level code example directory.
- Copy FreeRTOSConfig.h configuration file for the CM4(PSoC™ 6), CM33(CYW920829M2EVK-02/CYW989829M2EVB-01)or CM7(KIT_XMC72_EVK) from ota-update/<version>/configs/FreeRTOS directory to the top-level code example directory.
- Provide application version information in application makefile.
- OTA library user is expected to provide application version(X.Y.Z) by adding values for APP_VERSION_MAJOR, APP_VERSION_MINOR, and APP_VERSION_BUILD.
- Please refer to the ota-update/<version>/OTA_MAKEFILE_INFO_README.md file for more details on OTA application makefile.
- For HTTP support, add the following to the application Makefile:
- For MQTT support, add the following to the application Makefile:
- For Bluetooth® support, add the following to the application Makefile:
- OTA_MQTT_SUPPORT, OTA_HTTP_SUPPORT and OTA_BT_SUPPORT can be used simultaneously, but will possibly be too large to fit in the FLASH slot available.
- There are other COMPONENTS that may be needed based on support. Please refer to the various README.md files in the root ota-update library directory.
- README.md
- OTA_MAKEFILE_INFO_README.md
General Concept
The OTA Agent downloads upgrade version of OTA applications and stores the update to the upgrade slot using user registered storage callbacks. Once after completing the download, OTA library verifies update image(checksum) and reboots device. When device reboots, programmed bootloader boots upgrade image of application.
MCUBootloader - The basic device boot sequence is as follows:
- ROM boot will start Bootloader.
- Bootloader runs the current application in the BOOT slot.
- The OTA Agent downloads the update and stores it in the UPGRADE slot.
- The OTA Agent marks the upgrade as ready.
On the next system boot:
- ROM boot will start Bootloader
- If no update is downloaded, Bootloader starts the current application.
- Bootloader determines if there is an update in the UPGRADE Slot
- If there is an update available:
a. Bootloader verifies the update.
b. Bootloader starts the new (updated) application.
c. The updated application must validate the update.
CYW955913EVK-01 kit's in-built Bootloader - The basic device boot sequence is as follows:
- ROM boot will start CYW955913EVK-01 kit's in-built Bootloader.
- In-built Bootloader starts the current application in Active DS.
- If there is an update available in Non Active DS,
a. In-built Bootloader verifies the update image headers and certificates.
b. If a valid upgrade image is found, the in-built Bootloader will activate the non-active DS and deactivate the active DS.
c. On reset, in-built Bootloader starts the application in Active DS.
For more general information, see the various README.md files in the ota-update/<version>/ directory:
- README.md
- OTA_MAKEFILE_INFO_README.md
API Overview
Start the OTA Agent
cy_ota_start_agent()
is a non-blocking call, which returns a context pointer that is used in subsequent calls.
When using Bluetooth®, cy_ota_start_agent()
is called after the Peer sends a PREPARE_DOWNLOAD message.
When using MQTT or HTTP, the OTA Agent uses callbacks to signal the application when events occur.
cy_rslt_t cy_ota_agent_start(cy_ota_network_params_t *network_params, cy_ota_agent_params_t *agent_params, cy_ota_storage_interface_t *storage_interface, cy_ota_context_ptr *ctx_ptr);
These defines determine when the checks happen. Between checks, the OTA Agent is not connected to a server, and not checking for updates.
- CY_OTA_INITIAL_CHECK_SECS
- CY_OTA_NEXT_CHECK_INTERVAL_SECS
- CY_OTA_RETRY_INTERVAL_SECS
- CY_OTA_CHECK_TIME_SECS
Stop the OTA Agent
When you want to stop the OTA Agent.
cy_rslt_t cy_ota_agent_stop(cy_ota_context_ptr *ctx_ptr);
Trigger a check right now.
Use this when you want to trigger a check for an OTA update earlier than
is currently scheduled. The OTA Agent must have been started already. For MQTT and HTTP only.
cy_rslt_t cy_ota_get_update_now(cy_ota_context_ptr ctx_ptr);
Override Default Settings
For MQTT and HTTP usage, copy the cy_ota_config.h file from the ota-update/<version>/configs
directory to the top-level code example directory in the project.
Change these values to your preferred settings.
#define CY_OTA_INITIAL_CHECK_SECS (10)
#define CY_OTA_NEXT_CHECK_INTERVAL_SECS (24 * 60 * 60)
#define CY_OTA_RETRY_INTERVAL_SECS (5)
#define CY_OTA_CHECK_TIME_SECS (10 * 60)
#define CY_OTA_PACKET_INTERVAL_SECS (0)
#define CY_OTA_JOB_CHECK_TIME_SECS (30)
#define CY_OTA_DATA_CHECK_TIME_SECS (20 * 60)
#define CY_OTA_RETRIES (3)
#define CY_OTA_CONNECT_RETRIES (3)
#define CY_OTA_MAX_DOWNLOAD_TRIES (3)
#define CY_OTA_HTTP_TIMEOUT_SEND (3000)
#define CY_OTA_HTTP_TIMEOUT_RECEIVE (3000)
#define PUBLISHER_LISTEN_TOPIC "publish_notify"
#define COMPANY_TOPIC_PREPEND "OTAUpdate"
#define PUBLISHER_DIRECT_TOPIC "OTAImage"
#define CY_OTA_RESULT_SUCCESS "Success"
#define CY_OTA_RESULT_FAILURE "Failure"
#define CY_OTA_HTTP_JOB_FILE "/ota_update.json"
#define CY_OTA_HTTP_DATA_FILE "/ota-update.bin"
#define CY_OTA_SUBSCRIBE_UPDATES_AVAIL \
"{\
\"Message\":\"Update Availability\", \
\"Manufacturer\": \"Express Widgits Corporation\", \
\"ManufacturerID\": \"EWCO\", \
\"ProductID\": \"Easy Widgit\", \
\"SerialNumber\": \"ABC213450001\", \
\"BoardName\": \"CY8CPROTO_062_4343W\", \
\"Version\": \"%d.%d.%d\", \
\"UniqueTopicName\": \"%s\"\
}"
#define CY_OTA_DOWNLOAD_REQUEST \
"{\
\"Message\":\"Request Update\", \
\"Manufacturer\": \"Express Widgits Corporation\", \
\"ManufacturerID\": \"EWCO\", \
\"ProductID\": \"Easy Widgit\", \
\"SerialNumber\": \"ABC213450001\", \
\"BoardName\": \"CY8CPROTO_062_4343W\", \
\"Version\": \"%d.%d.%d\", \
\"UniqueTopicName\": \"%s\" \
}"
#define CY_OTA_DOWNLOAD_CHUNK_REQUEST \
"{\
\"Message\":\"Request Data Chunk\", \
\"Manufacturer\": \"Express Widgits Corporation\", \
\"ManufacturerID\": \"EWCO\", \
\"ProductID\": \"Easy Widgit\", \
\"SerialNumber\": \"ABC213450001\", \
\"BoardName\": \"CY8CPROTO_062_4343W\", \
\"Version\": \"%d.%d.%d\", \
\"UniqueTopicName\": \"%s\", \
\"Filename\": \"%s\", \
\"Offset\": \"%ld\", \
\"Size\": \"%ld\"\
}"
#define CY_OTA_MQTT_RESULT_JSON \
"{\
\"Message\":\"%s\", \
\"UniqueTopicName\": \"%s\"\
}"
#define CY_OTA_HTTP_RESULT_JSON \
"{\
\"Message\":\"%s\", \
\"File\":\"%s\" \
}"
#ifndef CY_OTA_HTTP_GET_TEMPLATE
#define CY_OTA_HTTP_GET_TEMPLATE \
"GET %s HTTP/1.1\r\n" \
"Host: %s:%d \r\n" \
"\r\n"
#endif
#ifndef CY_OTA_HTTP_GET_RANGE_TEMPLATE
#define CY_OTA_HTTP_GET_RANGE_TEMPLATE \
"GET %s HTTP/1.1\r\n" \
"Host: %s:%d \r\n" \
"Range: bytes=%ld-%ld \r\n" \
"\r\n"
#endif
#ifndef CY_OTA_HTTP_POST_TEMPLATE
#define CY_OTA_HTTP_POST_TEMPLATE \
"POST %s HTTP/1.1\r\n" \
"Content-Length:%ld \r\n" \
"\r\n%s"
#endif
#define CY_OTA_MQTT_KEEP_ALIVE_SECONDS (60)
#define CY_OTA_MQTT_MAX_TOPICS (2)
#define CY_OTA_MQTT_TOPIC_PREFIX "cy_ota_device"
#define CY_OTA_MQTT_CLIENT_ID_PREFIX "cy_device"
Bootloader Support
Starting from the 4.0 version of the ota-update library, the library is now fully separated from the MCUBootloader. This means that it can function independently and work with any bootloader, as long as the required OTA update handling storage APIs are implemented and registered with OTA agent by the user.
1. MCUBootloader Support
MCUBootloader is a secure bootloader for 32-bits microcontrollers and users should build it outside of the user OTA application. It is programmed separately to the device before flashing the user OTA application and is not updated for the life of the device. To support MCUBootloader based OTA using ota-update library, User can implement his own storage operation callbacks to handle upgrade image or can make use of ota-bootloader-abstraction library.
ota-bootloader-abstraction library has below support.
- Template flashmaps for PSoC6, 20829, 89829 and XMC7000 platforms.
- Template linker files for GCC_ARM, ARM, and IAR toolchains.
- Storage operation callback APIs to handle MCUBootloader based upgrade image.
- Prebuild and Postbuild scripts for generating and signing MCUBootloader based BOOT and UPGRADE image of an OTA Application.
2. In-built Bootloader Support on CYW955913EVK-01 kit
Platforms like CYW955913EVK-01 have in-built bootloader. To support OTA using ota-update library on CYW955913EVK-01 kit, user can implement his own storage operation callbacks to handle upgrade image or can make use of ota-bootloader-abstraction library.
ota-bootloader-abstraction library has below support for in-built bootloader based platforms like CYW955913EVK-01.
- Storage operation callback APIs to handle CYW955913EVK-01 in-built Bootloader based upgrade image.
User needs to register storage operation callbacks available in ota-bootloader-abstraction during OTA agent start.
For more information, see the various README.md files in the ota-bootloader-abstraction/<version>/ directory.
Code Snippets
MQTT and HTTP initialization:
The following code snippet demonstrates an example for initializing the cy_ota_network_params_t and ota_agent_params structures required to start the OTA Agent.
#define ENABLE_TLS (false)
#define HTTP_SERVER "my.httpserver.com"
#define HTTP_SERVER_PORT (80)
#define MQTT_TOPIC_FILTER_NUM (1)
#define MQTT_BROKER "mqtt.broker.com"
#define MQTT_BROKER_PORT (1883)
const char * mqtt_topics[ MQTT_TOPIC_FILTER_NUM ] =
{
"mtb/test/ota/image"
};
#define ROOT_CA_CERTIFICATE ""
#define CLIENT_CERTIFICATE ""
#define CLIENT_KEY ""
cy_awsport_ssl_credentials_t mqtt_credentials;
cy_awsport_ssl_credentials_t http_credentials;
{
.cb_arg = &ota_context,
.reboot_upon_completion = 1
};
{
.ota_file_read = cy_ota_storage_read,
.ota_file_write = cy_ota_storage_write,
.ota_file_close = cy_ota_storage_close,
.ota_file_verify = cy_ota_storage_verify,
.ota_file_validate = cy_ota_storage_validated,
.ota_file_get_app_info = cy_ota_storage_get_app_info
};
OTA flash operations callback:
This example functions demonstrates the usage of the OTA storage operation callbacks to handle upgrade image(read/write/erase). Implementation of storage operation callbacks is mandatory because OTA Agent depends on these callbacks for handling upgrade images.
Note: You must initialize Flash before registering these callbacks.
{
cy_rslt_t result = CY_RSLT_SUCCESS;
if(storage_ptr == NULL)
{
}
return result;
}
{
cy_rslt_t result = CY_RSLT_SUCCESS;
if(storage_ptr == NULL)
{
}
return result;
}
{
cy_rslt_t result = CY_RSLT_SUCCESS;
if(storage_ptr == NULL)
{
}
return result;
}
{
cy_rslt_t result = CY_RSLT_SUCCESS;
if(storage_ptr == NULL)
{
}
return result;
}
{
cy_rslt_t result = CY_RSLT_SUCCESS;
if(storage_ptr == NULL)
{
}
return result;
}
cy_rslt_t cy_ota_storage_validated(void)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
if(storage_ptr == NULL)
{
}
return result;
}
{
cy_rslt_t result = CY_RSLT_SUCCESS;
if(storage_ptr == NULL)
{
}
return result;
}
OTA Application callback:
This example function demonstrates the usage of the OTA callback function to print the status of every OTA event. The callback feature is optional but be aware that the OTA library will not print the status of the OTA Agent on its own.
Note: You must initialize retarget-io to use the debug UART port.
{
const char *state_string;
const char *error_string;
if (cb_data == NULL)
{
}
if (ctx == NULL)
{
}
{
break;
printf("APP CB OTA SUCCESS state:%d %s last_error:%s\n", cb_data->state, state_string, error_string);
break;
printf("APP CB OTA FAILURE state:%d %s last_error:%s\n", cb_data->state, state_string, error_string);
break;
switch (cb_data->state)
{
printf("APP CB OTA STATE CHANGE state:%d %s last_error:%s\n", cb_data->state, state_string, error_string);
break;
printf("APP CB OTA STATE CHANGE CY_OTA_STATE_START_UPDATE\n");
break;
printf("APP CB OTA STORAGE OPEN\n");
break;
break;
printf("APP CB OTA STORAGE CLOSE\n");
break;
printf("APP CB OTA CONNECT FOR JOB using ");
{
printf("MQTT: server:%s port: %d\n", cb_data->broker_server.pHostName, cb_data->broker_server.port);
}
else
{
printf("HTTP: server:%s port: %d\n", cb_data->broker_server.pHostName, cb_data->broker_server.port);
}
break;
printf("APP CB OTA JOB DOWNLOAD using ");
{
printf("MQTT: '%s'", cb_data->json_doc);
printf(" topic: '%s' \n", cb_data->unique_topic);
}
else
{
printf("HTTP: '%s'", cb_data->file);
}
break;
printf("APP CB OTA JOB DISCONNECT\n");
break;
printf("APP CB OTA PARSE JOB: '%.*s' \n", strlen(cb_data->json_doc), cb_data->json_doc);
break;
printf("APP CB OTA JOB REDIRECT\n");
break;
printf("APP CB OTA CONNECT FOR DATA using ");
{
printf("MQTT: %s:%d \n", cb_data->broker_server.pHostName, cb_data->broker_server.port);
}
else
{
printf("HTTP: %s:%d \n", cb_data->broker_server.pHostName, cb_data->broker_server.port);
}
break;
printf("APP CB OTA DATA DOWNLOAD using ");
{
printf("MQTT: '%s' \n", cb_data->json_doc);
printf(" topic: '%s' \n", cb_data->unique_topic);
}
else
{
printf("HTTP: '%s' \n", cb_data->json_doc);
printf(" file: '%s' \n", cb_data->file);
}
break;
printf("APP CB OTA DATA DISCONNECT\n");
break;
printf("APP CB OTA VERIFY\n");
break;
printf("APP CB OTA RESULT REDIRECT\n");
break;
printf("APP CB OTA SEND RESULT CONNECT using ");
{
printf("MQTT: Broker:%s port: %d\n", cb_data->broker_server.pHostName, cb_data->broker_server.port);
printf(" topic: '%s' \n", cb_data->unique_topic);
}
else
{
printf("HTTP: Server:%s port: %d\n", cb_data->broker_server.pHostName, cb_data->broker_server.port);
}
break;
printf("APP CB OTA SENDING RESULT using ");
{
printf("MQTT: '%s' \n", cb_data->json_doc);
}
else
{
printf("HTTP: '%s' \n", cb_data->json_doc);
}
break;
printf("APP CB OTA Got Result response\n");
break;
printf("APP CB OTA Result Disconnect\n");
break;
printf("APP CB OTA Session Complete\n");
break;
break;
}
break;
}
return cb_result;
}
OTA Initialization:
The following code snippet demonstrates the initialization of the OTA Agent.
cy_rslt_t ota_setup(void)
{
cy_rslt_t result;
if (cy_awsport_network_init() != CY_RSLT_SUCCESS)
{
printf("cy_awsport_network_init Failed.\n");
while(1)
{
cy_rtos_delay_milliseconds(10);
}
}
if (cy_mqtt_init() != CY_RSLT_SUCCESS )
{
printf("cy_mqtt_init() Failed.\n");
while(1)
{
cy_rtos_delay_milliseconds(10);
}
}
memset(&network_params, 0, sizeof(network_params));
memset(&agent_params, 0, sizeof(agent_params));
network_params.mqtt.broker.host_name = MQTT_BROKER;
network_params.mqtt.broker.port = MQTT_BROKER_PORT;
network_params.mqtt.numTopicFilters = MQTT_TOPIC_FILTER_NUM;
network_params.mqtt.pTopicFilters = mqtt_topics;
network_params.mqtt.pIdentifier = "MQTTClientUniqueIdentifier";
network_params.http.server.host_name = HTTP_SERVER;
network_params.http.server.port = HTTP_SERVER_PORT;
{
network_params.http.file = OTA_HTTP_JOB_FILE;
}
else
{
network_params.http.file = OTA_HTTP_DATA_FILE;
}
memset(&network_params.mqtt.credentials, 0x00, sizeof(network_params.mqtt.credentials) );
if (ota->mqtt_certificates == OTA_MQTT_SERVICE_AMAZON)
{
mqtt_credentials.username = "Test";
mqtt_credentials.username_size = strlen(mqtt_credentials.username);
mqtt_credentials.password = "";
mqtt_credentials.password_size = strlen(mqtt_credentials.password);
}
mqtt_credentials.alpnprotos = NULL;
mqtt_credentials.alpnprotoslen = 0;
mqtt_credentials.sni_host_name = NULL;
mqtt_credentials.sni_host_name_size = 0;
mqtt_credentials.root_ca = mqtt_root_ca_certificate_table[ota->mqtt_certificates];
mqtt_credentials.root_ca_size = strlen(mqtt_root_ca_certificate_table[ota->mqtt_certificates]) + 1;
mqtt_credentials.client_cert = mqtt_client_cert_table[ota->mqtt_certificates];
mqtt_credentials.client_cert_size = strlen(mqtt_client_cert_table[ota->mqtt_certificates]) + 1;
mqtt_credentials.private_key = mqtt_client_key_table[ota->mqtt_certificates];
mqtt_credentials.private_key_size = strlen(mqtt_client_key_table[ota->mqtt_certificates]) + 1;
if (ota->start_TLS)
{
network_params.mqtt.credentials = mqtt_credentials;
}
memset(&network_params.http.credentials, 0x00, sizeof(network_params.http.credentials ));
http_credentials.alpnprotos = NULL;
http_credentials.alpnprotoslen = 0;
http_credentials.sni_host_name = NULL;
http_credentials.sni_host_name_size = 0;
http_credentials.root_ca = (const char *)root_ca_certificate_https;
http_credentials.root_ca_size = strlen(root_ca_certificate_https) + 1;
http_credentials.client_cert = (const char *)client_cert_https;
http_credentials.client_cert_size = strlen(client_cert_https) + 1;
http_credentials.private_key = (const char *)client_key_https;
http_credentials.private_key_size = strlen(client_key_https) + 1;
if (ota->start_TLS)
{
network_params.http.credentials = http_credentials;
}
agent_params.validate_after_reboot = 0;
agent_params.reboot_upon_completion = 1;
agent_params.do_not_send_result = 0;
agent_params.cb_func = ota_callback;
agent_params.cb_arg = ota;
result =
cy_ota_agent_start(&network_params, &agent_params, &ota_interfaces, &ota_context);
return result;
}
Application Bluetooth® initialization:
The following code snippet demonstrates and example for initializing the Bluetooth® Stack required before starting the OTA Agent. The next snippet shows the Bluetooth® GATT callback handler.
static void bt_app_init(void)
{
wiced_result_t wiced_result;
wiced_bt_gatt_status_t status = WICED_BT_GATT_BUSY;
cybt_platform_config_init(&app_bt_platform_cfg_settings);
status = wiced_bt_gatt_register(app_bt_gatt_event_handler);
printf("wiced_bt_gatt_register() status (0x%lx) %s\n", status, app_get_gatt_status_name(status));
status = wiced_bt_gatt_db_init(gatt_database, gatt_database_len, NULL);
if(status != WICED_BT_GATT_SUCCESS)
{
printf("%s() wiced_bt_gatt_db_init() FAILED 0x%lx !\n", __func__, status);
}
wiced_bt_set_pairable_mode(WICED_TRUE, 0);
status = app_bt_set_advertisement_data();
if(status != WICED_SUCCESS)
{
printf("%s() app_bt_set_advertisement_data() FAILED 0x%lx !\n", __func__, status);
}
status = wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_HIGH, BLE_ADDR_PUBLIC, NULL);
if(status != WICED_SUCCESS)
{
printf("%s() wiced_bt_start_advertisements() FAILED 0x%lx\n", __func__, status);
}
wiced_result = wiced_bt_stack_init(app_bt_management_callback , &wiced_bt_cfg_settings);
if( WICED_BT_SUCCESS == wiced_result)
{
printf("Bluetooth(r) Stack Initialization Successful \n");
}
else
{
printf("Bluetooth(r) Stack Initialization failed!!\n");
}
}
Application Bluetooth® Callback Handling:
The following code snippet demonstrates and example for initializing the Bluetooth® Stack required before starting the OTA Agent.
static wiced_bt_gatt_status_t app_bt_gatt_event_handler(wiced_bt_gatt_evt_t event, wiced_bt_gatt_event_data_t *p_event_data)
{
wiced_bt_gatt_status_t status = WICED_BT_GATT_SUCCESS;
wiced_bt_gatt_attribute_request_t *p_attr_req = &p_event_data->attribute_request;
switch (event)
{
case GATT_CONNECTION_STATUS_EVT:
printf("\n\n%s() GATT_CONNECTION_STATUS_EVT: %d\n", __func__, event);
status = app_bt_connect_callback(&p_event_data->connection_status);
break;
case GATT_ATTRIBUTE_REQUEST_EVT:
printf("\n\n%s() GATT_ATTRIBUTE_REQUEST_EVT: %d type:%d\n", __func__, event, p_attr_req->opcode);
status = app_bt_server_callback(p_event_data);
break;
case GATT_GET_RESPONSE_BUFFER_EVT:
printf("\n\n%s() GATT_GET_RESPONSE_BUFFER_EVT\n", __func__);
p_event_data->buffer_request.buffer.p_app_rsp_buffer = app_bt_alloc_buffer (p_event_data->buffer_request.len_requested);
p_event_data->buffer_request.buffer.p_app_ctxt = (void*)app_bt_free_buffer;
status = WICED_BT_GATT_SUCCESS;
break;
case GATT_APP_BUFFER_TRANSMITTED_EVT:
printf("\n\n%s() GATT_APP_BUFFER_TRANSMITTED_EVT.\n", __func__);
{
pfn_free_buffer_t pfn_free = (pfn_free_buffer_t)p_event_data->buffer_xmitted.p_app_ctxt;
if (pfn_free)
pfn_free(p_event_data->buffer_xmitted.p_app_data);
status = WICED_BT_GATT_SUCCESS;
}
break;
case GATT_OPERATION_CPLT_EVT:
printf("\n\n%s() GATT_OPERATION_CPLT_EVT: We are a server, nothing to do.\n", __func__);
break;
default:
printf("\n\n%s()------------------> Unhandled GATT event: %d\n\n", __func__, event);
status = WICED_BT_GATT_SUCCESS;
break;
}
return status;
}
OTA Agent Bluetooth® initialization:
The following code snippet demonstrates starting the OTA Agent for use with Bluetooth®.
cy_rslt_t ota_setup(void)
{
cy_rslt_t result;
memset(&network_params, 0, sizeof(network_params));
memset(&agent_params, 0, sizeof(agent_params));
result =
cy_ota_agent_start(&network_params, &agent_params, &ota_interfaces, &ota_context);
return result;
}
ModusToolbox OTA Code Examples
ModusToolbox OTA Example using MQTT: https://github.com/infineon/mtb-example-ota-mqtt
ModusToolbox OTA Example using HTTP: https://github.com/Infineon/mtb-example-ota-https
ModusToolbox OTA Update Bluetooth® example: https://github.com/infineon/mtb-example-btstack-freertos-cyw20829-keyboard
ModusToolbox OTA Update Bluetooth® example: https://github.com/Infineon/mtb-example-btstack-freertos-cyw20829-battery-server-ota