replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / linux / SampleResourceServer.cpp
index fe4b6fb..9e919b6 100644 (file)
  *
  ******************************************************************/
 
-#include "PrimitiveResource.h"
 #include "RCSResourceObject.h"
+#include "RCSRequest.h"
 #include "OCPlatform.h"
-#include "OCApi.h"
 
-using namespace std;
-using namespace OC;
 using namespace OC::OCPlatform;
 using namespace OIC::Service;
 
-std::string resourceUri = "/a/TempSensor";
-std::string resourceType = "core.TemperatureSensor";
-std::string resourceInterface = "oic.if.";
-std::string attributeKey = "Temperature";
-RCSResourceObject::Ptr server;
+struct CloseApp{};
 
-//display the menu on the screen
-void displayMenu()
+constexpr int RESOURCE_TEMP = 1;
+constexpr int RESOURCE_LIGHT = 2;
+
+constexpr int DEFAULT_SERVER = 1;
+constexpr int CUSTOM_SERVER = 2;
+
+constexpr int INCREASE = 1;
+constexpr int DECREASE = 2;
+
+const std::string BASELINE_INTERFACE = "oic.if.baseline";
+const std::string ACTUATOR_INTERFACE = "oic.if.a";
+const std::string SENSOR_INTERFACE = "oic.if.s";
+const std::string CUSTOM_INTERFACE = "test.custom";
+
+typedef void (*DisplayControlMenuFunc)();
+typedef std::function<void()> Run;
+
+Run g_currentRun;
+
+bool g_isPresenceStarted = false;
+
+RCSResourceObject::Ptr g_resource;
+
+int processUserInput(int min, int max)
+{
+    assert(min <= max);
+
+    int input = 0;
+
+    std::cin >> input;
+
+    if (!std::cin.fail())
+    {
+        if (input == max + 1)
+        {
+            throw CloseApp();
+        }
+        if (min <= input && input <= max)
+        {
+            return input;
+        }
+    }
+
+    std::cin.clear();
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    throw std::runtime_error("Invalid Input, please try again");
+}
+
+void displayControlTemperatureMenu()
 {
-    std::cout << "=====================================================================\n\n";
-    std::cout << "   1 - Creation of Resource [Auto control for requests]" << std::endl;
-    std::cout << "   2 - Creation of Resource [Developer control for Get and Set requests]" <<std::endl;
-    std::cout << "   3 - Quit" << std::endl;
-    std::cout << "=====================================================================\n\n";
+    std::cout << "========================================================\n";
+    std::cout << INCREASE << ". Increase Temperature by 1 degree          \n";
+    std::cout << DECREASE << ". Decrease Temperature by 1 degree          \n";
+    std::cout << DECREASE + 1 << ". Quit                                  \n";
+    std::cout << "========================================================\n";
 }
 
-//hander for get request (if developer choose second option for resource Creation)
-RCSGetResponse RequestHandlerForGet(const RCSRequest &request,
-        RCSResourceAttributes &attrs)
+void displayControlLightMenu()
 {
-    cout << "Recieved a Get request from Client" << std::endl;
-    RCSResourceObject::LockGuard lock(*server);
-    RCSResourceAttributes attr = server->getAttributes();
-    RCSResourceAttributes::const_iterator iter = attr.begin();
-    cout << "\nSending response to Client : " << std::endl;
-    for (unsigned int i = 0; i < attr.size(); ++i)
+    std::cout << "========================================================\n";
+    std::cout << INCREASE << ". Increase Brightness by 1 stage            \n";
+    std::cout << DECREASE << ". Decrease Brightness by 1 stage            \n";
+    std::cout << DECREASE + 1 << ". Quit                                  \n";
+    std::cout << "========================================================\n";
+}
+
+void printAttributes(const RCSResourceAttributes& attrs)
+{
+    for (const auto& attr : attrs)
     {
-        std::cout << "\tkey : " << iter->key() << "\n\tvalue : " << iter->value().toString() << std::endl;
-        ++iter;
+        std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
+                  << attr.value().toString() << std::endl;
     }
-    return RCSGetResponse::create(attr);
 }
 
-//hander for set request (if developer choose second option for resource Creation)
-RCSSetResponse RequestHandlerForSet(const RCSRequest &request,
-        RCSResourceAttributes &attrs)
+RCSGetResponse requestHandlerForGet(const RCSRequest & req, RCSResourceAttributes& attrs)
 {
-    cout << "Recieved a Set request from Client" << std::endl;
-    RCSResourceAttributes::const_iterator iter = attrs.begin();
-    for (unsigned int i = 0; i < attrs.size(); ++i)
+    std::cout << "Received a Get request from Client" << std::endl;
+    printAttributes(attrs);
+
     {
-        std::cout << "\tkey : " << iter->key() << "\n\tvalue : " << iter->value().toString() << std::endl;
-        ++iter;
+        RCSResourceObject::LockGuard lock(g_resource);
+        std::cout << "\nSending response to Client : " << std::endl;
+        if (req.getInterface() == CUSTOM_INTERFACE)
+        {
+            auto attr = g_resource->getAttributes();
+            static RCSByteString::DataType binval {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+                                                   0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+            attr["blob"] = RCSByteString {binval};
+            printAttributes(attr);
+            return RCSGetResponse::create(attr);
+        }
+        else
+        {
+            printAttributes(g_resource->getAttributes());
+            return RCSGetResponse::defaultAction();
+        }
     }
-    iter = attrs.begin();
-    cout << "\n\nSending response to Client : " << std::endl;
-    for (unsigned int i = 0; i < attrs.size(); ++i)
+}
+
+RCSSetResponse requestHandlerForSet(const RCSRequest&, RCSResourceAttributes& attrs)
+{
+    std::cout << "Received a Set request from Client" << std::endl;
+    printAttributes(attrs);
+
+    return RCSSetResponse::defaultAction();
+}
+
+void initServer(const std::string& resourceUri, const std::string& resourceType,
+        const std::string& attrKey)
+{
+    g_resource = RCSResourceObject::Builder(resourceUri, resourceType, ACTUATOR_INTERFACE)
+            .addInterface(CUSTOM_INTERFACE)
+            .addInterface(SENSOR_INTERFACE)
+            .setDefaultInterface(BASELINE_INTERFACE)
+            .setDiscoverable(true)
+            .setObservable(true)
+            .build();
+
+    g_resource->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
+    g_resource->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
+    g_resource->setAttribute(attrKey, 0);
+}
+
+void updateAttribute(const std::string& attrKey, int control)
+{
+    const int diff = control == INCREASE ? 1 : - 1;
+
     {
-        std::cout << "\tkey : " << iter->key() << "\n\tvalue : " << iter->value().toString() << std::endl;
-        ++iter;
+        RCSResourceObject::LockGuard lock(g_resource);
+        auto& attrs = g_resource->getAttributes();
+        attrs[attrKey] = attrs[attrKey].get<int>() + diff;
     }
-    return RCSSetResponse::create(attrs);
+
+    if (control == INCREASE)
+    {
+        std::cout << attrKey << " increased." << std::endl;
+    }
+    else
+    {
+        std::cout << attrKey << " decreased." << std::endl;
+    }
+    std::cout << "\nCurrent " << attrKey << ": "
+            << g_resource->getAttributeValue(attrKey).get<int>() << std::endl;
 }
 
-int main(void)
+void runResourceControl(DisplayControlMenuFunc displayMenuFunc, const std::string& attrKey)
 {
+    displayMenuFunc();
+    updateAttribute(attrKey, processUserInput(INCREASE, DECREASE));
+}
 
-    int userInput;
-    int initialTemperature = 0;
-    int temperatureInput;
-    bool flag = true;
-    startPresence(3);
+void runResourceTypeSelection(int resourceMode)
+{
+    std::cout << "========================================================\n";
+    std::cout << "Select Resource Type                                    \n";
+    std::cout << RESOURCE_TEMP << ". Temperature                          \n";
+    std::cout << RESOURCE_LIGHT << ". Light                               \n";
+    std::cout << RESOURCE_LIGHT + 1 << ". Quit                            \n";
+    std::cout << "========================================================\n";
 
-    displayMenu();
+    int resourceType = processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT);
+    DisplayControlMenuFunc displayMenuFunc = nullptr;
+    std::string attrKey;
 
-    //userInput for creation of Resource
-    std::cin >> userInput;
-    std::cin.clear();
-    std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
-    try
+    switch (resourceType)
     {
-        while (flag)
-        {
+        case RESOURCE_TEMP:
+            attrKey = "Temperature";
+            initServer("/a/TempSensor", "oic.r.temperaturesensor", attrKey);
 
-            switch (userInput)
-            {
-
-                case 1:
-               //Creation of Resource & Auto control for all requests from Client
-                    {
-                        //creation of Resource
-                        server = RCSResourceObject::Builder(resourceUri, resourceType,
-                                                         resourceInterface).setDiscoverable(true).setObservable(false).build();
-                        std::cout << "Resource created successfully " << std::endl;
-
-                        //setting attribute for the Created Resource
-                        server->setAttribute(attributeKey, initialTemperature);
-                        flag = false;
-                        break;
-                    }
-
-                case 2:
-            //Creation of Resource & setting get and set handler for handling get and set request from client in application
-                    {
-                        server = RCSResourceObject::Builder(resourceUri, resourceType,
-                                                         resourceInterface).setDiscoverable(true).setObservable(false).build();
-                        std::cout << "Resource created successfully " << std::endl;
-
-                        //setting attribute for the Created Resource
-                        server->setAttribute(attributeKey, initialTemperature);
-
-                        //setting handler for handling get request from the client
-                        server->setGetRequestHandler(RequestHandlerForGet);
-
-                        //  setting handler for handling set request from the client
-                        server->setSetRequestHandler(RequestHandlerForSet);
-                        flag = false;
-                        break;
-                    }
-                case 3:
-                    return 0;
-                default :
-                    std::cout << "Invalid Input" << std::endl;
-                    break;
-            }
-        }
+            displayMenuFunc = displayControlTemperatureMenu;
+            break;
+
+        case RESOURCE_LIGHT:
+            attrKey = "Brightness";
+            initServer("/a/light", "oic.r.light", attrKey);
+
+            displayMenuFunc = displayControlLightMenu;
+            break;
+    }
+
+    if (resourceMode == CUSTOM_SERVER)
+    {
+        g_resource->setGetRequestHandler(requestHandlerForGet);
+        g_resource->setSetRequestHandler(requestHandlerForSet);
+    }
+
+    g_currentRun = std::bind(runResourceControl, displayMenuFunc, std::move(attrKey));
+}
+
+void runResourceModeSelection()
+{
+    std::cout << "========================================================          \n";
+    std::cout << DEFAULT_SERVER << ". Creation of Simple Resource Without Handlers  \n";
+    std::cout << CUSTOM_SERVER << ". Creation of Resource With Set and Get Handlers \n";
+    std::cout << CUSTOM_SERVER + 1 << ". Quit                                       \n";
+    std::cout << "========================================================          \n";
+
+    g_currentRun = std::bind(runResourceTypeSelection,
+            processUserInput(DEFAULT_SERVER, CUSTOM_SERVER));
+}
+
+void runPresenceSelection()
+{
+    constexpr int PRESENCE_ON = 1;
+    constexpr int PRESENCE_OFF = 2;
+
+    std::cout << "========================================================\n";
+    std::cout << PRESENCE_ON << ". Presence On                            \n";
+    std::cout << PRESENCE_OFF << ". Presence Off                          \n";
+    std::cout << PRESENCE_OFF + 1 << ". Quit                              \n";
+    std::cout << "========================================================\n";
+
+    if (processUserInput(PRESENCE_ON, PRESENCE_OFF) == PRESENCE_ON)
+    {
+        g_isPresenceStarted = true;
+        startPresence(3);
+    }
 
-        while (true)
+    g_currentRun = runResourceModeSelection;
+}
+
+int main(void)
+{
+    g_currentRun = runPresenceSelection;
+
+    while (true)
+    {
+        try
         {
-            bool end = false;
-            cout << endl;
-            cout << "========================================================" << endl;
-            cout << "1. Increase Temperature by 10 degree" << endl;
-            cout << "2. Decrease Temperature by 10 degree" << endl;
-            cout << "3. Stop the Sensor" << endl;
-            cout << "========================================================" << endl;
-
-            //user Input for increasing/decreasing the temperature
-            cin >> temperatureInput;
-            if (std::cin.fail())
-            {
-                std::cin.clear();
-                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
-                std::cout << "Invalid input type, please try again" << std::endl;
-                continue;
-            }
-
-            switch (temperatureInput)
-            {
-                case 1:
-                    {
-                        RCSResourceObject::LockGuard lock(*server);
-                        RCSResourceAttributes attrs = server->getAttributes();
-
-                        attrs[attributeKey] =  (server->getAttribute<int>(attributeKey)  + 10);
-                        server->setAttribute(attributeKey, attrs[attributeKey]);
-                        cout << "\nTemperature increased by 10 degree" << endl;
-
-                        //getting the current attribute and priniting it on the console
-                        attrs = server->getAttributes();
-                        cout << "\nCurrent Temperature : ";
-                        RCSResourceAttributes::const_iterator iter = attrs.begin();
-                        for (unsigned int i = 0; i < attrs.size(); ++i)
-                        {
-                            std::cout << iter->value().toString() << std::endl;
-                            ++iter;
-                        }
-                        break;
-                    }
-                case 2:
-                    {
-                        RCSResourceObject::LockGuard lock(*server);
-                        RCSResourceAttributes attrs = server->getAttributes();
-                        attrs[attributeKey] =  (server->getAttribute<int>(attributeKey)  - 10);
-                        server->setAttribute(attributeKey, attrs[attributeKey]);
-                        cout << "\nTemperature decreased by 10 degree" << endl;
-
-                        //getting the current attribute and priniting it on the console
-                        attrs = server->getAttributes();
-                        cout << "\nCurrent Temperature : ";
-                        RCSResourceAttributes::const_iterator iter = attrs.begin();
-                        for (unsigned int i = 0; i < attrs.size(); ++i)
-                        {
-                            std::cout << iter->value().toString() << std::endl;
-                            ++iter;
-                        }
-                        break;
-                    }
-                case 3:
-                    {
-                        cout << "Stopping the Resource" << endl;
-                        end = true;
-                        break;
-                    }
-                default:
-                    {
-                        cout << "Invalid input. Please try again." << endl;
-                        break;
-                    }
-            }
-            if (end == true)
-            {
-                server=NULL;
-                break;
-            }
+            g_currentRun();
+        }
+        catch (const std::exception& e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+        catch (const CloseApp&)
+        {
+            break;
         }
     }
-    catch (exception &e)
+    std::cout << "Stopping the server" << std::endl;
+
+    g_resource.reset();
+
+    if (g_isPresenceStarted)
     {
-        cout << "main exception  : " << e.what() << endl;
+        try
+        {
+            stopPresence();
+        }
+        catch(...)
+        {
+            std::cout << "presence stop fail" << std::endl;
+        }
     }
 }
 
-