set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++11")
if("${FLAVOR}" STREQUAL "UBUNTU")
- add_subdirectory(secserver)
add_definitions(-D__BUILD_UBUNTU__)
endif()
return host;
}
- const std::string& getRouting() const override
+ const std::string& getParent() const override
{
return hub_uuid;
}
char* model;
char* type;
DeviceState state;
+ char* parent;
} NM_DeviceInfo;
typedef enum {
{
typedef std::function<void(const std::string&, bool)> PresenceHook;
-constexpr char NOTIFICATION_URI[] = "/secserver/notification";
-constexpr char NOTIFICATION_TYPE[] = "secserver.notification";
const int NOTIFICATION_TESTCODE = 557291712;
class SecurityContext
std::string user_login;
std::string password;
std::string m_uid;
+
+ bool subscribed;
};
} // namespace NetworkManager
// nmdaemon configuration path
const std::string INI_FILE_PATH{CONF_PREFIX "/etc/nmdaemon/nmdaemon.conf"};
// default iotcloud IP (local SRK server)
-const std::string DEFAULT_CLOUD_IP{"106.125.46.44"};
+const std::string DEFAULT_CLOUD_IP{"106.125.46.139"};
// default iotcloud port
const int DEFAULT_CLOUD_PORT = 5683;
static std::string cloud_host;
// default DSM URI (local SRK server)
-const std::string DEFAULT_DSM_URI{"http://106.125.46.74:8080/dsm/restapi/"};
+const std::string DEFAULT_DSM_URI{"http://106.125.46.139:8080/dsm/restapi/"};
static std::string dsm_uri;
bool file_exists(const std::string& file_name)
info->name = nullptr;
info->model = nullptr;
info->type = nullptr;
+ info->parent = nullptr;
try
{
info->model = toASCIIZ(dev->getModel());
info->type = toASCIIZ(dev->getType());
info->state = dev->isOnline() == true ? DS_Online : DS_Offline;
+ info->parent = toASCIIZ(dev->getParent());
}
catch (NMexception& e)
{
try
{
- DeviceControl control(ctx->instance->host(), dev_id, ctx->instance);
- result = control.deleteApp(app_name, parentUuid);
+ std::string parent{parentUuid};
+ if (parent.empty())
+ {
+ parent = dev_id;
+ }
+
+ DeviceControl control(ctx->instance->host(), parent, ctx->instance);
+ result = control.deleteApp(app_name, dev_id);
}
catch(NMexception& e)
{
{
Json::Reader parser;
Json::Value contents;
+
if (!parser.parse(json, contents, false))
{
LOG_E(TAG, "wrong JSON format");
model = contents["model"].asString();
}
- IoTDevicePtr device = std::make_shared<IoTDevice_impl>(uuid, name, type, model);
+ std::string parentUuid("");
+
+ if (contents.isMember("parentUuid"))
+ {
+ parentUuid = contents["parentUuid"].asString();
+ }
+
+ IoTDevicePtr device = std::make_shared<IoTDevice_impl>(uuid, name, type, model, parentUuid);
device->setState(false);
return device;
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
+#define NOTIFICATION_TYPE "secserver.notification"
+
namespace
{
const std::string NOTIF_FIND = "Notification findResource()";
-const std::string NOTIF_REQUEST = string(OC_RSRVD_WELL_KNOWN_URI) + "?rt=" + NetworkManager::NOTIFICATION_TYPE;
+const std::string NOTIF_REQUEST = OC_RSRVD_WELL_KNOWN_URI "?rt=" NOTIFICATION_TYPE;
const std::string POLICY_TOPIC{"/srv/policy"};
int stoi_secure(const std::string& val, int default_val = 0)
rest_service.signUp(user_login, uid);
}
-SecurityContext::SecurityContext(IoTivity* iotivity) : iotivity(iotivity)
+SecurityContext::SecurityContext(IoTivity* iotivity) : iotivity(iotivity), subscribed(false)
{
if (iotivity == nullptr)
{
return;
}
+ LOG_D(TAG, "Notification received");
+ printRepresentation(rep);
CallbackState callbackState = NORMAL_CALLBACK;
if (sequenceNumber == 0)
std::string user_notification_topic = "/" + iotivity->getCloudAuthId() + "/notification";
mq->subscribe(user_notification_topic, observCb);
+ subscribed = true;
}
void SecurityContext::unsubscribeNotifications()
{
FN_VISIT;
+ if (!subscribed) return;
IMqClient* mq = iotivity->getMqHandler();
std::string user_notification_topic = "/" + iotivity->getCloudAuthId() + "/notification";
mq->unsubscribe(user_notification_topic);
+/**
+ * @brief Resource client class used to send specific commands to the device.
+ * @date Created 30.08.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ * between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ * and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ * Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
+
#ifndef DEVICE_CONTROL_H
#define DEVICE_CONTROL_H
IotResourceServer(const std::string& uri, const std::string& type, const std::vector<std::string>& interfaces);
+ virtual ~IotResourceServer();
+
/**
* @brief entityHandler - resource users request handler (called by OCF)
* @param request [in] request for resource
virtual const std::string& getHost() const = 0;
/**
- * @brief getRouting return routing information for device
- * @return QueryParamsMap with routing information
+ * @brief return parent device id or empty string if has no parent
+ * @return uuid of parent device as string
*/
- virtual const std::string& getRouting() const = 0;
+ virtual const std::string& getParent() const = 0;
/**
* @brief isOnline checks if device is online
IoTDevice_impl(std::shared_ptr<OC::OCResource> device_resource, bool connected = true);
- IoTDevice_impl(const std::string& uid, const std::string& device_name, const std::string& device_type, const std::string& device_model);
+ IoTDevice_impl(const std::string& uid,
+ const std::string& device_name,
+ const std::string& device_type,
+ const std::string& device_model,
+ const std::string& device_parent = std::string{});
~IoTDevice_impl() override;
return host;
}
- const std::string& getRouting() const override
+ const std::string& getParent() const override
{
- return uuid;
+ return parentUuid;
}
bool isOnline() const override
std::string uuid;
std::string spec_ver;
std::string host;
+ std::string parentUuid;
bool online;
bool cloud_accessibility;
};
+/**
+ * @brief Resource client class used to send specific commands to the device.
+ * @date Created 30.08.2017
+ * @author Created 2017 in Samsung Ukraine R&D Center (SURC) under a contract
+ * between LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine)
+ * and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea).
+ * Copyright: (c) Samsung Electronics Co, Ltd 2017. All rights reserved.
+ * @author Mail to: <A HREF="mailto:d.lomtev@samsung.com">Dmytro Lomtev, d.lomtev@samsung.com</A>
+ */
#include "device_control.h"
#include "device_commands.h"
#include "nmexceptions.h"
}
}
+IotResourceServer::~IotResourceServer()
+{
+ if (m_handle != nullptr)
+ {
+ OC::OCPlatform::unregisterResource(m_handle);
+ }
+}
+
OCEntityHandlerResult IotResourceServer::entityHandler(std::shared_ptr<OC::OCResourceRequest> request)
{
OCEntityHandlerResult res = OC_EH_ERROR;
LOG_D(TAG, "Device found [%s]:[%s] connectivity=0x%08x.", name.c_str(), uuid.c_str(), int(dev->connectivityType()));
}
-IoTDevice_impl::IoTDevice_impl(const std::string& uid, const std::string& device_name, const std::string& device_type, const std::string& device_model)
- : dev(nullptr), name(device_name), model(device_model), type(device_type), uuid(uid), spec_ver("unknown"), host(""), online(false), cloud_accessibility(false)
+IoTDevice_impl::IoTDevice_impl(
+ const std::string& uid,
+ const std::string& device_name,
+ const std::string& device_type,
+ const std::string& device_model,
+ const std::string& device_parent)
+ : dev(nullptr)
+ , name(device_name)
+ , model(device_model)
+ , type(device_type)
+ , uuid(uid)
+ , spec_ver("unknown")
+ , host("")
+ , parentUuid(device_parent)
+ , online(false)
+ , cloud_accessibility(false)
{
}
{
model = std::move(value);
}
+
+ parentUuid = "";
}
}
#include "nmexceptions.h"
#include <OCApi.h>
#include <OCPlatform.h>
+#include "logging.h"
+#include "network_manager_tag.h"
using namespace OC;
void printRepresentation(const OCRepresentation& rep)
{
+ LOG_D(TAG, "[Representation BEGIN]");
for (auto itr = rep.begin(); itr != rep.end(); ++itr)
{
- std::cout << "\t" << itr->attrname() << ":\t" << itr->getValueToString() << std::endl;
+ LOG_D(TAG, "\t%s:\t%s", itr->attrname().c_str(), itr->getValueToString().c_str());
if (itr->type() == AttributeType::Vector)
{
switch (itr->base_type())
case AttributeType::Integer:
for (auto itr2 : (*itr).getValue<std::vector<int> >())
{
- std::cout << "\t\t" << itr2 << std::endl;
+ LOG_D(TAG, "\t\t%d", itr2);
}
break;
case AttributeType::String:
for (auto itr2 : (*itr).getValue<std::vector<std::string> >())
{
- std::cout << "\t\t" << itr2 << std::endl;
+ LOG_D(TAG, "\t\t%s", itr2.c_str());
}
break;
default:
- std::cout << "Unhandled base type " << itr->base_type() << std::endl;
+ LOG_D(TAG, "Unhandled base type %d", int(itr->base_type()));
break;
}
}
printRepresentation((*itr).getValue<OCRepresentation>());
}
}
+ LOG_D(TAG, "[Representation END]");
}
void guardTimeout(bool timeout, const std::string& message)
QualityOfService::HighQos), "discoveryMQTopics()");
callback->wait();
-
OCResource::Ptr resource;
- int r = std::try_lock(callback->mtx, handler_mutex);
- if (-1 == r)
- {
+ while(-1 != std::try_lock(callback->mtx, handler_mutex));
- std::for_each(callback->topics.begin(), callback->topics.end(),
- [this] (OCResource::Ptr ptr)
+ std::for_each(callback->topics.begin(), callback->topics.end(),
+ [this] (OCResource::Ptr ptr)
+ {
+ if (topicCache.find(ptr->uri()) == topicCache.end())
{
- if (topicCache.find(ptr->uri()) == topicCache.end())
- {
- topicCache[ptr->uri()] = ptr;
- }
+ topicCache[ptr->uri()] = ptr;
}
- );
-
- auto it = topicCache.find(topic.getName());
- if (it != topicCache.end())
- {
- resource = it->second;
}
+ );
- callback->mtx.unlock();
- handler_mutex.unlock();
- }
+ auto it = topicCache.find(topic.getName());
+ if (it != topicCache.end())
+ {
+ resource = it->second;
+ }
+
+ callback->mtx.unlock();
+ handler_mutex.unlock();
return resource;
}
AuditTrailClient* client = reinterpret_cast<AuditTrailClient*>(user_data);
assert(client);
- client->m_proxy_thread->addAction(std::async(std::launch::deferred, &AuditTrailClient::sendReport, client, std::string{log}));
+ client->m_proxy_thread->addDefferedTask(&AuditTrailClient::sendReport, client, std::string{log});
}
AuditTrailClient::AuditTrailClient(const std::string& device_id, std::shared_ptr<ProxyThread> proxy_thread, std::shared_ptr<ReportHandler> report_handler, WorkingMode mode)
if (duid == m_iotivity->getDeviceID())
{
+ LOG_D(TAG, "Request for this device");
result = 0 == ApplicationService::uninstall(name);
}
else
{
+ LOG_D(TAG, "Request for device: %s", duid.c_str());
+
if ((result = m_hub->isOwned(duid)))
{
+ LOG_D(TAG, "Proxying uninstall request");
NetworkManager::IoTivity* iot = m_iotivity;
auto deleter = [duid, iot, name]
{
control.deleteApp(name, duid);
};
- m_proxy_thread->addAction(std::async(std::launch::deferred, deleter));
+ m_proxy_thread->addDefferedTask(deleter);
}
}
bool CommandHandler::unOwnCommand(const OC::OCRepresentation& command)
{
- m_proxy_thread->addAction(std::async(std::launch::deferred, &CommandHandler::unOwnTask, this));
+ m_proxy_thread->addDefferedTask(&CommandHandler::unOwnTask, this);
return true;
}
if (bool(proxy))
{
- proxy->addAction(std::async(&PolicyHandler::pass, policy_handler, rep, qp));
+ proxy->addDefferedTask(&PolicyHandler::pass, policy_handler, rep, qp);
}
if(OC_STACK_OK == OCPlatform::sendResponse(pResponse))
if (proxy)
{
LOG_D(TAG, "Proxy add action: report pass");
- proxy->addAction(std::async(std::launch::deferred, &ReportHandler::pass, &report_handler, rep, query));
+ proxy->addDefferedTask(&ReportHandler::pass, &report_handler, rep, query);
}
}
catch(std::exception& e)
if (state == "own")
{
- m_proxy_thread->addAction(std::async(std::launch::deferred, &HubResource::ownDevice, this, id));
+ m_proxy_thread->addDefferedTask(&HubResource::ownDevice, this, id);
res = OC_EH_OK;
}
else if (state == "unown")
{
- m_proxy_thread->addAction(std::async(std::launch::deferred, &HubResource::unownDevice, this, id));
+ m_proxy_thread->addDefferedTask(&HubResource::unownDevice, this, id);
res = OC_EH_OK;
}
}
#include <condition_variable>
#include <queue>
#include "thread_base.h"
-#include <iostream>
+#include "logging.h"
class ProxyThread : public NMD::ThreadBase
{
public:
ProxyThread()
{
-
}
- void addAction(std::future<void>&& action)
+ template<typename Func, typename... Args>
+ void addDefferedTask(Func&& func, Args&&... args)
{
std::unique_lock<std::mutex> lock{mtx};
- deferred.push(std::move(action));
+ deferred.push(std::async(std::launch::deferred, std::forward<Func>(func), std::forward<Args>(args)...));
notice.notify_one();
}
}
catch (std::exception& e)
{
- std::cout << "proxy execute Exception: " << e.what() << std::endl << std::flush;
+ LOG_E("nmdaemon", "proxy execute Exception: %s", e.what());
}
catch (...)
{
- std::cout << "proxy execute Unknown Exception" << std::endl << std::flush;
+ LOG_E("nmdaemon", "proxy execute Unknown Exception");
}
lock.lock();
deferred.pop();
#include <chrono>
#include "iotivity.h"
-std::string cloud_host{"coap+tcp://106.125.46.44:5683"};
+std::string cloud_host{"coap+tcp://106.125.46.139:5683"};
std::string TEST_ACCOUNT_LOGIN{"admin@samsung.com"};
std::string TEST_ACCOUNT_PASSWORD{"111111"};
-/**
- * @brief Child process routing for resource initialization used in functional tests
- * @return 0 - Ok, -1 - error
- */
-int child_process_routine();
-
-void signal_handler(int signal)
-{
- if (signal == SIGUSR1)
- {
- NetworkManager::IoTivity::cleanUp();
- exit(0);
- }
-}
-
int main(int argc, char** argv)
{
- auto sig_result = signal(SIGUSR1, signal_handler);
- if (SIG_ERR == sig_result)
- {
- std::cout << "Failed to setup TERM signal handler" << std::endl;
- return -1;
- }
-
NetworkManager::IoTivity::setPersistentStoragePath("/tmp/temporary_persitent_storage.dat");
- pid_t pid = fork();
-
- if (pid < 0)
- {
- std::cout << "Failed to fork" << std::endl;
- return -1;
- }
-
- if (pid == 0)
- {
- return child_process_routine();
- }
-
- int result = -1;
-
- std::this_thread::sleep_for(std::chrono::seconds(1));
-
try
{
if (argc > 1 && argv[1][0] != '-')
cloud_host = std::string{"coap+tcp://"} + argv[1] + std::string{":5683"};
}
::testing::InitGoogleTest(&argc, argv);
-// ::testing::InitGoogleMock(&argc, argv);
- result = RUN_ALL_TESTS();
+ return RUN_ALL_TESTS();
}
catch (std::exception& e)
{
std::cout << "Unknown exception" << std::endl;
}
- kill(pid, SIGUSR1);
- return result;
+ return -1;
}
const std::string test_executable_package_name = test_executable + ".1.2.3.4.rpm";
}
-class ISystemMock
-{
-public:
- virtual int system(const char*) = 0;
- virtual void popen(const char*, const char*) = 0;
- virtual ~ISystemMock() {};
-};
-
-class SystemMock : public ISystemMock
-{
-public:
- MOCK_METHOD1(system, int (const char* cmd));
- MOCK_METHOD2(popen, void (const char* file, const char* mode));
- ~SystemMock() {};
-};
-
-SystemMock systemMock;
-
-int system(const char* cmd)
-{
- return systemMock.system(cmd);
-}
-
-FILE* popen(const char *command, const char *type)
-{
- systemMock.popen(command, type);
- return fopen(test_rpm_query_stub_path.c_str(), "r");
-}
-
-
TEST(test_commandhandler, test_uninstallTask)
{
- std::string system_cmd = "rpm -e " + test_executable_package_name + " > /dev/null";
- std::string popen_cmd = "rpm -qa | grep " + test_executable;
-
- EXPECT_CALL(systemMock, popen(StrEq(popen_cmd.c_str()), StrEq("r")))
- .Times(1);
- EXPECT_CALL(systemMock, system(StrEq(system_cmd.c_str())))
- .Times(1)
- .WillOnce(Return(0));
-
-
- std::ofstream f{test_rpm_query_stub_path};
- f << "package.1" << std::endl
- << test_executable_package_name << std::endl
- << "package.2" << std::endl;
- f.close();
-
try
{
+ IoTivity::cleanUp();
IoTivity* iot = IoTivity::getInstance();
std::shared_ptr<ProxyThread> proxy = std::make_shared<ProxyThread>();
std::shared_ptr<HubResource> hub = std::make_shared<HubResource>(iot, proxy, std::string{""});
{
FAIL() << "Exception: " << e.what();
}
-
- EXPECT_EQ(0, remove(test_rpm_query_stub_path.c_str()));
}
* 1. Search for hub resource
* 2. Obtain list of owned primitive devices
*/
-TEST_F(IoTDevManagerTest, hub_owned_discovery)
+TEST_F(IoTDevManagerTest, DISABLED_hub_owned_discovery)
{
try
{
* 1. Search for hub resource
* 2. Obtain list of unowned primitive devices
*/
-TEST_F(IoTDevManagerTest, hub_unowned_discovery)
+TEST_F(IoTDevManagerTest, DISABLED_hub_unowned_discovery)
{
try
{
{
char* agents = nullptr;
ASSERT_EQ(EC_NULL_POINTER, NM_getDeviceAgents(ctx, nullptr, &agents));
+ if (uid == nullptr) return;
ASSERT_EQ(EC_OK, NM_getDeviceAgents(ctx, uid, &agents));
ASSERT_NE(nullptr, agents);
const std::string name = "Test device";
const std::string type = "iotdevice";
const std::string model = "test model";
- IoTDevice_impl dev(uuid, name, type, model);
+ const std::string parent = "0987654321";
+ IoTDevice_impl dev(uuid, name, type, model, parent);
EXPECT_EQ(uuid, dev.getUUID());
EXPECT_EQ(name, dev.getName());
EXPECT_EQ(type, dev.getType());
EXPECT_EQ(model, dev.getModel());
- EXPECT_EQ(uuid, dev.getRouting());
+ EXPECT_EQ(parent, dev.getParent());
EXPECT_FALSE(dev.isCloudAccessibility());
EXPECT_FALSE(dev.isOnline());
EXPECT_FALSE(dev.isActive());
- OCResource::Ptr ctrl_resource = iot->findResource("", "device.control");
-
- if(!ctrl_resource)
- {
- throw std::runtime_error("Test control resource not found");
- }
-
OCConnectivityType connectivityType = CT_DEFAULT;
- std::string host = ctrl_resource->host();
+ std::string host = "coap://192.168.1.2:5683";
std::string uri = "/resource";
std::vector<std::string> types = {"intel.rpost"};
std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
- ASSERT_FALSE(host.empty());
-
auto res = OCPlatform::constructResourceObject(host, uri, connectivityType, false, types, ifaces);
ASSERT_FALSE(!res) << "Resource not constructed";
EXPECT_TRUE(dev.isActive());
EXPECT_TRUE(dev.isOnline());
- EXPECT_NO_THROW(dev.unOwnDevice());
-
dev.deactivate();
EXPECT_FALSE(dev.isOnline());
EXPECT_FALSE(dev.isActive());
int result = 0;
- proxy.addAction(async(launch::deferred, [&result]{
+ proxy.addDefferedTask([&result]{
result = 42;
- }));
+ });
proxy.stop();
proxy.join();
OC::OCRepresentation representation1;
representation1.setValue("duid", DUID);
representation1.setValue("uuid", UUID);
- representation1.setValue("parentUuid", DUID);
+ representation1.setValue("parentUuid", std::string{""});
representation1.setValue("name", NAME);
representation1.setValue("model", MODEL);
representation1.setValue("type", TYPE);
extern std::string cloud_host;
extern std::string TEST_ACCOUNT_LOGIN;
extern std::string TEST_ACCOUNT_PASSWORD;
-const std::string TEST_DSM_SERVER_URL = "http://106.125.46.74:8080/dsm/restapi/";
+const std::string TEST_DSM_SERVER_URL = "http://106.125.46.139:8080/dsm/restapi/";
#define TAG "Tests"