1717#include " dfu/ota/ota_util.h"
1818
1919#include < platform/CHIPDeviceLayer.h>
20+ #include < platform/nrfconnect/DFUSync.h>
2021
2122#include < lib/support/logging/CHIPLogging.h>
2223
@@ -37,25 +38,38 @@ constexpr static uint16_t kAdvertisingIntervalMin = 400;
3738constexpr static uint16_t kAdvertisingIntervalMax = 500 ;
3839constexpr static uint8_t kAdvertisingFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR;
3940
41+ static bool sDfuInProgress = false ;
42+ static uint32_t sDfuSyncMutexId ;
43+
4044namespace
4145{
42- enum mgmt_cb_return UploadConfirmHandler(uint32_t event , enum mgmt_cb_return prev_status , int32_t *rc, uint16_t *group ,
43- bool *abort_more , void *data, size_t data_size )
46+ enum mgmt_cb_return UploadConfirmHandler(uint32_t , enum mgmt_cb_return, int32_t *rc, uint16_t *,
47+ bool *, void *data, size_t )
4448{
4549/* Currently img_mgmt hooks are not supported by SUIT */
4650#ifndef CONFIG_SUIT
4751 const img_mgmt_upload_check &imgData = *static_cast <img_mgmt_upload_check *>(data);
4852 IgnoreUnusedVariable (imgData);
4953
54+ if (!sDfuInProgress ) {
55+ if (DFUSync::GetInstance ().Take (sDfuSyncMutexId ) == CHIP_NO_ERROR) {
56+ sDfuInProgress = true ;
57+ } else {
58+ ChipLogError (SoftwareUpdate, " Cannot start DFU over SMP, another DFU in progress." );
59+ *rc = MGMT_ERR_EBUSY;
60+ return MGMT_CB_ERROR_RC;
61+ }
62+ }
63+
5064 ChipLogProgress (SoftwareUpdate, " DFU over SMP progress: %u/%u B of image %u" ,
5165 static_cast <unsigned >(imgData.req ->off ), static_cast <unsigned >(imgData.action ->size ),
5266 static_cast <unsigned >(imgData.req ->image ));
5367#endif
5468 return MGMT_CB_OK;
5569}
5670
57- enum mgmt_cb_return CommandHandler(uint32_t event, enum mgmt_cb_return prev_status , int32_t *rc , uint16_t *group ,
58- bool *abort_more , void *data , size_t data_size )
71+ enum mgmt_cb_return CommandHandler(uint32_t event, enum mgmt_cb_return, int32_t *, uint16_t *,
72+ bool *, void *, size_t )
5973{
6074 if (event == MGMT_EVT_OP_CMD_RECV) {
6175 Nrf::Matter::GetFlashHandler ().DoAction (ExternalFlashManager::Action::WAKE_UP);
@@ -66,6 +80,14 @@ enum mgmt_cb_return CommandHandler(uint32_t event, enum mgmt_cb_return prev_stat
6680 return MGMT_CB_OK;
6781}
6882
83+ enum mgmt_cb_return DfuStoppedHandler(uint32_t , enum mgmt_cb_return, int32_t *, uint16_t *,
84+ bool *, void *, size_t )
85+ {
86+ DFUSync::GetInstance ().Free (sDfuSyncMutexId );
87+
88+ return MGMT_CB_OK;
89+ }
90+
6991mgmt_callback sUploadCallback = {
7092 .callback = UploadConfirmHandler,
7193 .event_id = MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK,
@@ -76,11 +98,20 @@ mgmt_callback sCommandCallback = {
7698 .event_id = (MGMT_EVT_OP_CMD_RECV | MGMT_EVT_OP_CMD_DONE),
7799};
78100
101+ mgmt_callback sDfuStopped = {
102+ .callback = DfuStoppedHandler,
103+ .event_id = (MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED | MGMT_EVT_OP_IMG_MGMT_DFU_PENDING),
104+ };
105+
79106} /* namespace */
80107
81108namespace Nrf
82109{
83110
111+ BT_CONN_CB_DEFINE (conn_callbacks) = {
112+ .disconnected = DFUOverSMP::Disconnected,
113+ };
114+
84115DFUOverSMP DFUOverSMP::sDFUOverSMP ;
85116
86117void DFUOverSMP::Init ()
@@ -106,6 +137,7 @@ void DFUOverSMP::Init()
106137
107138 mgmt_callback_register (&sUploadCallback );
108139 mgmt_callback_register (&sCommandCallback );
140+ mgmt_callback_register (&sDfuStopped );
109141}
110142
111143void DFUOverSMP::ConfirmNewImage ()
@@ -136,4 +168,19 @@ void DFUOverSMP::StartServer()
136168 ChipLogProgress (DeviceLayer, " DFU over SMP started" );
137169}
138170
171+ void DFUOverSMP::Disconnected (bt_conn *conn, uint8_t reason)
172+ {
173+ bt_conn_info btInfo;
174+
175+ VerifyOrReturn (sDfuInProgress );
176+ VerifyOrReturn (bt_conn_get_info (conn, &btInfo) == 0 );
177+
178+ // Drop all callbacks incoming for the role other than peripheral, required by the Matter accessory
179+ VerifyOrReturn (btInfo.role == BT_CONN_ROLE_PERIPHERAL);
180+
181+ sDfuInProgress = false ;
182+
183+ DFUSync::GetInstance ().Free (sDfuSyncMutexId );
184+ }
185+
139186} /* namespace Nrf */
0 commit comments