2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Mateusz Malicki <m.malicki2@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
22 * @author Mateusz Malicki (m.malicki2@samsung.com)
23 * @brief This file contains vasum-server's client implementation
26 //TODO: Make dispatcher related function thread-safe.
27 //For now vsm_connect, vsm_get_dispatcher_type, vsm_set_dispatcher_type,
28 //vsm_get_poll_fd, vsm_enter_eventloop can't be used at the same time.
29 //TODO: Make vsm_get_status_message thread-safe version (vsm_get_status_message_r)
32 #include "vasum-client-impl.hpp"
34 #include "exception.hpp"
35 #include "utils/exception.hpp"
36 #include "logger/logger.hpp"
37 #include "host-ipc-definitions.hpp"
38 #include "ipc/client.hpp"
39 #include "api/messages.hpp"
46 #include <arpa/inet.h>
49 #include <boost/algorithm/string/split.hpp>
50 #include <boost/algorithm/string/classification.hpp>
53 using namespace utils;
54 using namespace vasum;
58 const int TIMEOUT_INFINITE = -1;
60 VsmZoneState getZoneState(const char* state)
62 if (strcmp(state, "STOPPED") == 0) {
64 } else if (strcmp(state, "STARTING") == 0) {
66 } else if (strcmp(state, "RUNNING") == 0) {
68 } else if (strcmp(state, "STOPPING") == 0) {
70 } else if (strcmp(state, "ABORTING") == 0) {
72 } else if (strcmp(state, "FREEZING") == 0) {
74 } else if (strcmp(state, "FROZEN") == 0) {
76 } else if (strcmp(state, "THAWED") == 0) {
78 } else if (strcmp(state, "LOCKED") == 0) {
80 } else if (strcmp(state, "MAX_STATE") == 0) {
82 } else if (strcmp(state, "ACTIVATING") == 0) {
85 throw InvalidResponseException("Unknown state");
88 void convert(const api::VectorOfStrings& in, VsmArrayString& out)
90 out = reinterpret_cast<char**>(calloc(in.values.size() + 1, sizeof(char*)));
91 for (size_t i = 0; i < in.values.size(); ++i) {
92 out[i] = ::strdup(in.values[i].c_str());
96 void convert(const api::ZoneInfoOut& info, VsmZone& zone)
98 VsmZone vsmZone = reinterpret_cast<VsmZone>(malloc(sizeof(*vsmZone)));
99 vsmZone->id = ::strdup(info.id.c_str());
100 vsmZone->terminal = info.vt;
101 vsmZone->state = getZoneState(info.state.c_str());
102 vsmZone->rootfs_path = ::strdup(info.rootPath.c_str());
106 string toString(const in_addr* addr)
108 char buf[INET_ADDRSTRLEN];
109 const char* ret = inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
111 throw InvalidArgumentException(getSystemErrorMessage());
116 string toString(const in6_addr* addr)
118 char buf[INET6_ADDRSTRLEN];
119 const char* ret = inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN);
121 throw InvalidArgumentException(getSystemErrorMessage());
126 bool readFirstLineOfFile(const string& path, string& ret)
139 #define IS_SET(param) \
141 throw InvalidArgumentException(#param " is not set"); \
144 Client::Status::Status()
145 : mVsmStatus(VSMCLIENT_SUCCESS), mMsg()
149 Client::Status::Status(VsmStatus status, const string& msg)
150 : mVsmStatus(status), mMsg(msg)
154 Client::Client() noexcept
158 Client::~Client() noexcept
162 bool Client::isConnected() const
164 return mClient && mClient->isStarted();
167 bool Client::isInternalDispatcherEnabled() const
169 return static_cast<bool>(mInternalDispatcher);
172 ipc::epoll::EventPoll& Client::getEventPoll() const
174 if ((mInternalDispatcher && mEventPoll) || (!mInternalDispatcher && !mEventPoll)) {
175 throw OperationFailedException("Can't determine dispatcher method");
178 if (isInternalDispatcherEnabled()) {
179 return mInternalDispatcher->getPoll();
185 VsmStatus Client::coverException(const function<void(void)>& worker) noexcept
190 mStatus = Status(VSMCLIENT_SUCCESS);
191 } catch (const IOException& ex) {
192 mStatus = Status(VSMCLIENT_IO_ERROR, ex.what());
193 } catch (const OperationFailedException& ex) {
194 mStatus = Status(VSMCLIENT_OPERATION_FAILED, ex.what());
195 } catch (const InvalidArgumentException& ex) {
196 mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
197 } catch (const InvalidResponseException& ex) {
198 mStatus = Status(VSMCLIENT_OTHER_ERROR, ex.what());
199 } catch (const ClientException& ex) {
200 mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what());
201 } catch (const ipc::IPCUserException& ex) {
202 mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what());
203 } catch (const ipc::IPCException& ex) {
204 mStatus = Status(VSMCLIENT_IO_ERROR, ex.what());
205 } catch (const exception& ex) {
206 mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what());
208 VsmStatus ret = mStatus.mVsmStatus;
209 mStatusMutex.unlock();
213 VsmStatus Client::connectSystem() noexcept
215 return connect(HOST_IPC_SOCKET);
218 VsmStatus Client::connect(const std::string& address) noexcept
220 return coverException([&] {
221 if (!mInternalDispatcher && !mEventPoll) {
222 vsm_set_dispatcher_type(VSMDISPATCHER_INTERNAL);
224 mClient.reset(new ipc::Client(getEventPoll(), address));
229 VsmStatus Client::disconnect() noexcept
231 return coverException([&] {
236 VsmStatus Client::vsm_get_poll_fd(int* fd) noexcept
238 return coverException([&] {
240 if (isInternalDispatcherEnabled()) {
241 throw OperationFailedException("Can't get event fd from internal dispatcher");
243 *fd = mEventPoll->getPollFD();
247 VsmStatus Client::vsm_enter_eventloop(int /* flags */, int timeout) noexcept
249 return coverException([&] {
250 if (isInternalDispatcherEnabled()) {
251 throw OperationFailedException("Can't enter to event loop of internal dispatcher");
253 mEventPoll->dispatchIteration(timeout);
257 VsmStatus Client::vsm_set_dispatcher_type(VsmDispacherType dispacher) noexcept
259 return coverException([&] {
261 throw OperationFailedException("Can't change dispacher");
264 case VSMDISPATCHER_INTERNAL:
265 mInternalDispatcher.reset(new ipc::epoll::ThreadDispatcher());
268 case VSMDISPATCHER_EXTERNAL:
269 mEventPoll.reset(new ipc::epoll::EventPoll());
270 mInternalDispatcher.reset();
273 throw OperationFailedException("Unsupported EventDispacher type");
278 VsmStatus Client::vsm_get_dispatcher_type(VsmDispacherType* dispacher) noexcept
280 return coverException([&] {
283 if (isInternalDispatcherEnabled()) {
284 *dispacher = VSMDISPATCHER_INTERNAL;
286 *dispacher = VSMDISPATCHER_EXTERNAL;
291 const char* Client::vsm_get_status_message() const noexcept
293 return mStatus.mMsg.c_str();
296 VsmStatus Client::vsm_get_status() const noexcept
298 lock_guard<mutex> lock(mStatusMutex);
299 return mStatus.mVsmStatus;
302 VsmStatus Client::vsm_get_zone_dbuses(VsmArrayString* /*keys*/, VsmArrayString* /*values*/) noexcept
304 return coverException([&] {
305 //TODO: Remove vsm_get_zone_dbuses from API
306 throw OperationFailedException("Not implemented");
310 VsmStatus Client::vsm_lock_queue() noexcept
312 return coverException([&] {
313 *mClient->callSync<api::Void, api::Void>(
314 vasum::api::ipc::METHOD_LOCK_QUEUE,
315 std::make_shared<api::Void>());
319 VsmStatus Client::vsm_unlock_queue() noexcept
321 return coverException([&] {
322 *mClient->callSync<api::Void, api::Void>(
323 vasum::api::ipc::METHOD_UNLOCK_QUEUE,
324 std::make_shared<api::Void>());
328 VsmStatus Client::vsm_get_zone_ids(VsmArrayString* array) noexcept
330 return coverException([&] {
333 api::ZoneIds zoneIds = *mClient->callSync<api::Void, api::ZoneIds>(
334 vasum::api::ipc::METHOD_GET_ZONE_ID_LIST,
335 std::make_shared<api::Void>());
336 convert(zoneIds, *array);
340 VsmStatus Client::vsm_get_active_zone_id(VsmString* id) noexcept
342 return coverException([&] {
345 api::ZoneId zoneId = *mClient->callSync<api::Void, api::ZoneId>(
346 api::ipc::METHOD_GET_ACTIVE_ZONE_ID,
347 std::make_shared<api::Void>());
348 *id = ::strdup(zoneId.value.c_str());
352 VsmStatus Client::vsm_get_zone_rootpath(const char* id, VsmString* rootpath) noexcept
354 return coverException([&] {
358 api::ZoneInfoOut info = *mClient->callSync<api::ZoneId, api::ZoneInfoOut>(
359 api::ipc::METHOD_GET_ZONE_INFO,
360 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
361 *rootpath = ::strdup(info.rootPath.c_str());
365 VsmStatus Client::vsm_lookup_zone_by_pid(int pid, VsmString* id) noexcept
367 return coverException([&] {
370 const string path = "/proc/" + to_string(pid) + "/cpuset";
373 if (!readFirstLineOfFile(path, cpuset)) {
374 throw InvalidArgumentException("Process not found");
378 if (!parseZoneIdFromCpuSet(cpuset, zoneId)) {
379 throw OperationFailedException("unknown format of cpuset");
382 *id = ::strdup(zoneId.c_str());
386 VsmStatus Client::vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept
388 return coverException([&] {
392 api::ZoneInfoOut info = *mClient->callSync<api::ZoneId, api::ZoneInfoOut>(
393 api::ipc::METHOD_GET_ZONE_INFO,
394 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
395 convert(info, *zone);
399 VsmStatus Client::vsm_lookup_zone_by_terminal_id(int, VsmString*) noexcept
401 return coverException([&] {
402 //TODO: Implement vsm_lookup_zone_by_terminal_id
403 throw OperationFailedException("Not implemented");
407 VsmStatus Client::vsm_set_active_zone(const char* id) noexcept
409 return coverException([&] {
412 mClient->callSync<api::ZoneId, api::Void>(
413 api::ipc::METHOD_SET_ACTIVE_ZONE,
414 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
418 VsmStatus Client::vsm_create_zone(const char* id, const char* tname) noexcept
420 return coverException([&] {
423 string template_name = tname ? tname : "default";
424 mClient->callSync<api::CreateZoneIn, api::Void>(
425 api::ipc::METHOD_CREATE_ZONE,
426 std::make_shared<api::CreateZoneIn>(api::CreateZoneIn{ id, template_name }),
431 VsmStatus Client::vsm_destroy_zone(const char* id) noexcept
433 return coverException([&] {
435 mClient->callSync<api::ZoneId, api::Void>(
436 api::ipc::METHOD_DESTROY_ZONE,
437 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
442 VsmStatus Client::vsm_shutdown_zone(const char* id) noexcept
444 return coverException([&] {
446 mClient->callSync<api::ZoneId, api::Void>(
447 api::ipc::METHOD_SHUTDOWN_ZONE,
448 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
453 VsmStatus Client::vsm_start_zone(const char* id) noexcept
455 return coverException([&] {
457 mClient->callSync<api::ZoneId, api::Void>(
458 api::ipc::METHOD_START_ZONE,
459 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
464 VsmStatus Client::vsm_lock_zone(const char* id) noexcept
466 return coverException([&] {
468 mClient->callSync<api::ZoneId, api::Void>(
469 api::ipc::METHOD_LOCK_ZONE,
470 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
475 VsmStatus Client::vsm_unlock_zone(const char* id) noexcept
477 return coverException([&] {
479 mClient->callSync<api::ZoneId, api::Void>(
480 api::ipc::METHOD_UNLOCK_ZONE,
481 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
485 VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateFunction /* zoneDbusStateCallback */,
487 VsmSubscriptionId* /* subscriptionId */) noexcept
489 return coverException([&] {
490 //TODO: Implement vsm_add_state_callback
491 throw OperationFailedException("Not implemented");
495 VsmStatus Client::vsm_del_state_callback(VsmSubscriptionId subscriptionId) noexcept
497 return coverException([&] {
498 mClient->removeMethod(subscriptionId);
502 VsmStatus Client::vsm_grant_device(const char* id, const char* device, uint32_t flags) noexcept
504 return coverException([&] {
508 mClient->callSync<api::GrantDeviceIn, api::Void>(
509 api::ipc::METHOD_GRANT_DEVICE,
510 std::make_shared<api::GrantDeviceIn>(api::GrantDeviceIn{ id, device, flags }));
514 VsmStatus Client::vsm_revoke_device(const char* id, const char* device) noexcept
516 return coverException([&] {
520 mClient->callSync<api::RevokeDeviceIn, api::Void>(
521 api::ipc::METHOD_REVOKE_DEVICE,
522 std::make_shared<api::RevokeDeviceIn>(api::RevokeDeviceIn{ id, device }));
526 VsmStatus Client::vsm_zone_get_netdevs(const char* id, VsmArrayString* netdevIds) noexcept
528 return coverException([&] {
532 api::NetDevList netdevs = *mClient->callSync<api::ZoneId, api::NetDevList>(
533 api::ipc::METHOD_GET_NETDEV_LIST,
534 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
535 convert(netdevs, *netdevIds);
539 VsmStatus Client::vsm_netdev_get_ip_addr(const char* id,
540 const char* netdevId,
544 using namespace boost::algorithm;
546 return coverException([&] {
551 api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
552 api::ipc::METHOD_GET_NETDEV_ATTRS,
553 std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
555 auto it = find_if(attrs.values.begin(),
557 [type](const api::StringPair& entry) {
558 return entry.first == (type == AF_INET ? "ipv4" : "ipv6");
561 if (it != attrs.values.end()) {
562 vector<string> addrAttrs;
563 for(auto addrAttr : split(addrAttrs, it->second, is_any_of(","))) {
564 size_t pos = addrAttr.find(":");
565 if (addrAttr.substr(0, pos) == "ip") {
566 if (pos != string::npos && pos < addrAttr.length() &&
567 inet_pton(type, addrAttr.substr(pos + 1).c_str(), addr) == 1) {
568 //XXX: return only one address
571 throw InvalidResponseException("Wrong address format returned");
576 throw OperationFailedException("Address not found");
580 VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* id,
581 const char* netdevId,
582 struct in_addr* addr) noexcept
584 return vsm_netdev_get_ip_addr(id, netdevId, AF_INET, addr);
587 VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* id,
588 const char* netdevId,
589 struct in6_addr* addr) noexcept
591 return vsm_netdev_get_ip_addr(id, netdevId, AF_INET6, addr);
594 VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id,
595 const char* netdevId,
596 struct in_addr* addr,
599 return coverException([&] {
604 string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
605 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
606 api::ipc::METHOD_SET_NETDEV_ATTRS,
607 std::make_shared<api::SetNetDevAttrsIn>(
608 api::SetNetDevAttrsIn{ id, netdevId, { { "ipv4", value } } }));
612 VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* id,
613 const char* netdevId,
614 struct in6_addr* addr,
617 return coverException([&] {
622 string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
623 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
624 api::ipc::METHOD_SET_NETDEV_ATTRS,
625 std::make_shared<api::SetNetDevAttrsIn>(
626 api::SetNetDevAttrsIn{ id, netdevId, { { "ipv6", value } } }));
630 VsmStatus Client::vsm_netdev_del_ipv4_addr(const char* id,
631 const char* netdevId,
632 struct in_addr* addr,
635 return coverException([&] {
641 string ip = toString(addr) + "/" + to_string(prefix);
642 mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
643 api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
644 std::make_shared<api::DeleteNetdevIpAddressIn>(
645 api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
649 VsmStatus Client::vsm_netdev_del_ipv6_addr(const char* id,
650 const char* netdevId,
651 struct in6_addr* addr,
654 return coverException([&] {
660 string ip = toString(addr) + "/" + to_string(prefix);
661 mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
662 api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
663 std::make_shared<api::DeleteNetdevIpAddressIn>(
664 api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
669 VsmStatus Client::vsm_netdev_up(const char* id, const char* netdevId) noexcept
671 return coverException([&] {
675 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
676 api::ipc::METHOD_SET_NETDEV_ATTRS,
677 std::make_shared<api::SetNetDevAttrsIn>(
678 api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(IFF_UP) },
679 { "change", to_string(IFF_UP) } } }));
683 VsmStatus Client::vsm_netdev_down(const char* id, const char* netdevId) noexcept
685 return coverException([&] {
689 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
690 api::ipc::METHOD_SET_NETDEV_ATTRS,
691 std::make_shared<api::SetNetDevAttrsIn>(
692 api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(~IFF_UP) },
693 { "change", to_string(IFF_UP) } } }));
697 VsmStatus Client::vsm_create_netdev_veth(const char* id,
699 const char* hostDev) noexcept
701 return coverException([&] {
706 mClient->callSync<api::CreateNetDevVethIn, api::Void>(
707 api::ipc::METHOD_CREATE_NETDEV_VETH,
708 std::make_shared<api::CreateNetDevVethIn>(
709 api::CreateNetDevVethIn{ id, zoneDev, hostDev }));
713 VsmStatus Client::vsm_create_netdev_macvlan(const char* id,
716 enum macvlan_mode mode) noexcept
718 return coverException([&] {
723 mClient->callSync<api::CreateNetDevMacvlanIn, api::Void>(
724 api::ipc::METHOD_CREATE_NETDEV_MACVLAN,
725 std::make_shared<api::CreateNetDevMacvlanIn>(
726 api::CreateNetDevMacvlanIn{ id, zoneDev, hostDev, mode }));
730 VsmStatus Client::vsm_create_netdev_phys(const char* id, const char* devId) noexcept
732 return coverException([&] {
736 mClient->callSync<api::CreateNetDevPhysIn, api::Void>(
737 api::ipc::METHOD_CREATE_NETDEV_PHYS,
738 std::make_shared<api::CreateNetDevPhysIn>(
739 api::CreateNetDevPhysIn{ id, devId }));
743 VsmStatus Client::vsm_lookup_netdev_by_name(const char* id,
744 const char* netdevId,
745 VsmNetdev* netdev) noexcept
747 using namespace boost::algorithm;
749 return coverException([&] {
754 api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
755 api::ipc::METHOD_GET_NETDEV_ATTRS,
756 std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
757 auto it = find_if(attrs.values.begin(),
759 [](const api::StringPair& entry) {
760 return entry.first == "type";
764 if (it == attrs.values.end()) {
765 throw OperationFailedException("Can't fetch netdev type");
768 switch (stoi(it->second)) {
769 case 1<<0 /*IFF_802_1Q_VLAN*/: type = VSMNETDEV_VETH; break;
770 case 1<<21 /*IFF_MACVLAN*/: type = VSMNETDEV_MACVLAN; break;
772 throw InvalidResponseException("Unknown netdev type: " + it->second);
775 *netdev = reinterpret_cast<VsmNetdev>(malloc(sizeof(**netdev)));
776 (*netdev)->name = ::strdup(id);
777 (*netdev)->type = type;
781 VsmStatus Client::vsm_destroy_netdev(const char* id, const char* devId) noexcept
783 return coverException([&] {
787 mClient->callSync<api::DestroyNetDevIn, api::Void>(
788 api::ipc::METHOD_DESTROY_NETDEV,
789 std::make_shared<api::DestroyNetDevIn>(api::DestroyNetDevIn{ id, devId }));
793 VsmStatus Client::vsm_declare_file(const char* id,
798 VsmString* declarationId) noexcept
800 return coverException([&] {
804 api::Declaration declaration = *mClient->callSync<api::DeclareFileIn, api::Declaration>(
805 api::ipc::METHOD_DECLARE_FILE,
806 std::make_shared<api::DeclareFileIn>(
807 api::DeclareFileIn{ id, type, path, flags, (int)mode }));
808 if (declarationId != NULL) {
809 *declarationId = ::strdup(declaration.value.c_str());
814 VsmStatus Client::vsm_declare_mount(const char *source,
820 VsmString* declarationId) noexcept
822 return coverException([&] {
831 api::Declaration declaration = *mClient->callSync<api::DeclareMountIn, api::Declaration>(
832 api::ipc::METHOD_DECLARE_MOUNT,
833 std::make_shared<api::DeclareMountIn>(
834 api::DeclareMountIn{ source, id, target, type, flags, data }));
835 if (declarationId != NULL) {
836 *declarationId = ::strdup(declaration.value.c_str());
841 VsmStatus Client::vsm_declare_link(const char* source,
844 VsmString* declarationId) noexcept
846 return coverException([&] {
851 api::Declaration declaration = *mClient->callSync<api::DeclareLinkIn, api::Declaration>(
852 api::ipc::METHOD_DECLARE_LINK,
853 std::make_shared<api::DeclareLinkIn>(api::DeclareLinkIn{ source, id, target }));
854 if (declarationId != NULL) {
855 *declarationId = ::strdup(declaration.value.c_str());
860 VsmStatus Client::vsm_list_declarations(const char* id, VsmArrayString* declarations) noexcept
862 return coverException([&] {
864 IS_SET(declarations);
866 api::Declarations declarationsOut = *mClient->callSync<api::ZoneId, api::Declarations>(
867 api::ipc::METHOD_GET_DECLARATIONS,
868 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
869 convert(declarationsOut, *declarations);
873 VsmStatus Client::vsm_remove_declaration(const char* id, VsmString declaration) noexcept
875 return coverException([&] {
879 mClient->callSync<api::RemoveDeclarationIn, api::Void>(
880 api::ipc::METHOD_REMOVE_DECLARATION,
881 std::make_shared<api::RemoveDeclarationIn>(api::RemoveDeclarationIn{ id, declaration }));
885 VsmStatus Client::vsm_notify_active_zone(const char* /*application*/, const char* /*message*/) noexcept
887 return coverException([&] {
888 //TODO: Implement vsm_notify_active_zone
889 throw OperationFailedException("Not implemented");
893 VsmStatus Client::vsm_file_move_request(const char* /*destZone*/, const char* /*path*/) noexcept
895 return coverException([&] {
896 //TODO: Implement vsm_file_move_request
897 throw OperationFailedException("Not implemented");
901 VsmStatus Client::vsm_add_notification_callback(VsmNotificationFunction /*notificationCallback*/,
903 VsmSubscriptionId* /*subscriptionId*/) noexcept
905 return coverException([&] {
906 //TODO: Implement vsm_add_notification_callback
907 throw OperationFailedException("Not implemented");
911 VsmStatus Client::vsm_del_notification_callback(VsmSubscriptionId subscriptionId) noexcept
913 return coverException([&] {
914 mClient->removeMethod(subscriptionId);