diff --git a/smocore/deviceManager/deviceManager.cpp b/smocore/deviceManager/deviceManager.cpp index eef7dac..2df14fa 100644 --- a/smocore/deviceManager/deviceManager.cpp +++ b/smocore/deviceManager/deviceManager.cpp @@ -95,6 +95,104 @@ public: } }; +class DeviceManager::RemoveDeviceAttachmentSpecReq +: public PostedAsynchronousContinuation +{ +public: + RemoveDeviceAttachmentSpecReq( + const std::shared_ptr &s, + const std::shared_ptr &caller, + Callback cb) + : PostedAsynchronousContinuation( + caller, cb), + spec(s) + {} + +public: + void removeDeviceAttachmentSpecReq1_posted( + [[maybe_unused]] std::shared_ptr context + ) + { + // Call detachSenseDeviceReq first - only clean up metadata if this succeeds + DeviceManager::getInstance().detachSenseDeviceReq( + spec, + {context, std::bind( + &RemoveDeviceAttachmentSpecReq::removeDeviceAttachmentSpecReq2, + context.get(), context, + std::placeholders::_1, std::placeholders::_2)}); + } + + void removeDeviceAttachmentSpecReq2( + [[maybe_unused]] std::shared_ptr context, + bool success, + std::shared_ptr deviceSpec + ) + { + if (!success) + { + // Detach failed, callback with failure (metadata remains intact) + callOriginalCb(false, deviceSpec); + return; + } + + // Detach succeeded, now find and clean up metadata + try { + // Find the DeviceRole in attachedDeviceRoles + auto deviceRoleIt = std::find_if( + attachedDeviceRoles.begin(), + attachedDeviceRoles.end(), + [&spec = spec](const std::shared_ptr &role) { + return *role->deviceAttachmentSpec == *spec; + } + ); + + if (deviceRoleIt == attachedDeviceRoles.end()) + { + // DeviceRole not found, callback with failure + callOriginalCb(false, deviceSpec); + return; + } + + auto deviceRole = *deviceRoleIt; + auto& device = deviceRole->parentDevice; + + // Remove DeviceRole from DeviceManager's collection + attachedDeviceRoles.erase(deviceRoleIt); + + // Remove DeviceRole from Device's collection + auto deviceRoleIt2 = std::find( + device.deviceRoles.begin(), + device.deviceRoles.end(), + deviceRole); + if (deviceRoleIt2 != device.deviceRoles.end()) + { + device.deviceRoles.erase(deviceRoleIt2); + } + + // Remove DeviceAttachmentSpec from deviceAttachmentSpecs collection + auto specIt = std::find_if( + deviceAttachmentSpecs.begin(), + deviceAttachmentSpecs.end(), + [&spec = spec](const std::shared_ptr &existingSpec) { + return *existingSpec == *spec; + }); + if (specIt != deviceAttachmentSpecs.end()) + { + deviceAttachmentSpecs.erase(specIt); + } + + // Callback with success + callOriginalCb(true, deviceSpec); + } catch (const std::exception& e) { + // Cleanup failed, callback with error + callOriginalCb(false, deviceSpec); + } + } + +public: + std::shared_ptr spec; +}; + void DeviceManager::newDeviceAttachmentSpecInd( const DeviceAttachmentSpec &spec, Callback callback) @@ -177,6 +275,39 @@ void DeviceManager::newDeviceAttachmentSpecInd( continuation.get(), continuation)); } +void DeviceManager::removeDeviceAttachmentSpecReq( + const DeviceAttachmentSpec &spec, + Callback callback) +{ + // Find the shared_ptr to the spec in the collection + std::shared_ptr specPtr = nullptr; + for (const auto& existingSpec : deviceAttachmentSpecs) + { + if (*existingSpec == spec) + { + specPtr = existingSpec; + break; + } + } + + if (!specPtr) + { + // Spec not found, callback with failure + callback.callbackFn(false, nullptr); + return; + } + + // Create async continuation + const auto& caller = ComponentThread::getSelf(); + auto continuation = std::make_shared( + specPtr, caller, callback); + + mrntt::mrntt.thread->getIoService().post( + std::bind( + &RemoveDeviceAttachmentSpecReq::removeDeviceAttachmentSpecReq1_posted, + continuation.get(), continuation)); +} + class DeviceManager::AttachSenseDeviceReq : public PostedAsynchronousContinuation { diff --git a/smocore/include/deviceManager/deviceManager.h b/smocore/include/deviceManager/deviceManager.h index cd095d6..ec3df66 100644 --- a/smocore/include/deviceManager/deviceManager.h +++ b/smocore/include/deviceManager/deviceManager.h @@ -39,14 +39,20 @@ public: static const std::string stringifyDeviceSpecs(void); - // New async function for device attachment typedef std::function deviceRole, std::shared_ptr deviceSpec)> newDeviceAttachmentSpecIndCbFn; + typedef std::function deviceSpec)> + removeDeviceAttachmentSpecReqCbFn; + void newDeviceAttachmentSpecInd( - const DeviceAttachmentSpec &spec, - Callback callback); + const DeviceAttachmentSpec &spec, + Callback callback); + void removeDeviceAttachmentSpecReq( + const DeviceAttachmentSpec &spec, + Callback callback); // Device attachment/detachment methods moved from SenseApiManager typedef sense_api::sal_mlo_attachDeviceReqCbFn attachSenseDeviceReqCbFn; @@ -87,6 +93,7 @@ public: private: class NewDeviceAttachmentSpecInd; + class RemoveDeviceAttachmentSpecReq; class AttachSenseDeviceReq; typedef AttachSenseDeviceReq DetachSenseDeviceReq; class AttachAllSenseDevicesFromSpecsReq;