replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / linux / SampleResourceServer.cpp
index b1c67cf..9e919b6 100644 (file)
  *
  ******************************************************************/
 
-#include "PrimitiveResource.h"
 #include "RCSResourceObject.h"
+#include "RCSRequest.h"
 #include "OCPlatform.h"
-#include "OCApi.h"
 
-using namespace OC;
 using namespace OC::OCPlatform;
 using namespace OIC::Service;
 
-constexpr int DEFALUT_VALUE = 0;
+struct CloseApp{};
 
-constexpr int REQUEST_TEMP = 1;
-constexpr int REQUEST_LIGHT = 2;
+constexpr int RESOURCE_TEMP = 1;
+constexpr int RESOURCE_LIGHT = 2;
 
-constexpr int PRESENCE_ON = 1;
-constexpr int PRESENCE_OFF = 2;
-
-constexpr int DEFALUT_SERVER = 1;
+constexpr int DEFAULT_SERVER = 1;
 constexpr int CUSTOM_SERVER = 2;
-constexpr int STOP = 3;
-
-constexpr int INCREASE_TEMPERATURE = 1;
-constexpr int DECREASE_TEMPERATURE = 2;
-constexpr int STOP_TEMPERATURE_SENSOR = 3;
-constexpr int STOP_LIGHT_SENSOR = 1;
 
-constexpr int CORRECT_INPUT = 1;
-constexpr int INCORRECT_INPUT = 2;
-constexpr int QUIT = 3;
+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";
 
-std::string resourceUri = "/a/TempSensor";
-std::string resourceType = "core.TemperatureSensor";
-std::string resourceInterface = "oic.if.";
-std::string attributeKey = "Temperature";
-int isPresenceOn = PRESENCE_ON;
+typedef void (*DisplayControlMenuFunc)();
+typedef std::function<void()> Run;
 
-RCSResourceObject::Ptr server;
+Run g_currentRun;
 
-int processUserInput();
+bool g_isPresenceStarted = false;
 
-enum class Control{
-    INCREASE,
-    DECREASE
-};
+RCSResourceObject::Ptr g_resource;
 
-void displayMenu()
+int processUserInput(int min, int max)
 {
-    std::cout << "====================================================================="
-              << std::endl;
-    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 << "====================================================================="
-              << std::endl;
+    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 << "========================================================" << std::endl;
-    std::cout << "1. Increase Temperature by 10 degree" << std::endl;
-    std::cout << "2. Decrease Temperature by 10 degree" << std::endl;
-    std::cout << "3. Stop the Sensor" << std::endl;
-    std::cout << "========================================================" << std::endl;
+    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";
 }
 
 void displayControlLightMenu()
 {
-    std::cout << "========================================================" << std::endl;
-    std::cout << "1. Stop the Sensor" << std::endl;
-    std::cout << "========================================================" << std::endl;
+    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 printAttribute(const RCSResourceAttributes& attrs)
+void printAttributes(const RCSResourceAttributes& attrs)
 {
-    for(const auto& attr : attrs)
+    for (const auto& attr : attrs)
     {
         std::cout << "\tkey : " << attr.key() << "\n\tvalue : "
                   << attr.value().toString() << std::endl;
     }
 }
 
-//hander for get request (if developer choose second option for resource Creation)
-RCSGetResponse requestHandlerForGet(const RCSRequest& request,
-        RCSResourceAttributes& attrs)
+RCSGetResponse requestHandlerForGet(const RCSRequest & req, RCSResourceAttributes& attrs)
 {
-    std::cout << "Recieved a Get request from Client" << std::endl;
-    RCSResourceObject::LockGuard lock(*server);
-    RCSResourceAttributes attributes = server->getAttributes();
-
-    std::cout << "\nSending response to Client : " << std::endl;
-    printAttribute(attributes);
+    std::cout << "Received a Get request from Client" << std::endl;
+    printAttributes(attrs);
 
-    return RCSGetResponse::defaultAction();
+    {
+        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();
+        }
+    }
 }
 
-//hander for set request (if developer choose second option for resource Creation)
-RCSSetResponse requestHandlerForSet(const RCSRequest& request,
-        RCSResourceAttributes& attrs)
+RCSSetResponse requestHandlerForSet(const RCSRequest&, RCSResourceAttributes& attrs)
 {
-    std::cout << "Recieved a Set request from Client" << std::endl;
+    std::cout << "Received a Set request from Client" << std::endl;
+    printAttributes(attrs);
 
-    std::cout << "\n\nSending response to Client : " << std::endl;
-    RCSResourceObject::LockGuard lock(*server);
-    printAttribute(attrs);
     return RCSSetResponse::defaultAction();
 }
 
-void createResource()
+void initServer(const std::string& resourceUri, const std::string& resourceType,
+        const std::string& attrKey)
 {
-    server = RCSResourceObject::Builder(resourceUri, resourceType,resourceInterface).
-            setDiscoverable(true).setObservable(true).build();
+    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 initServer()
+void updateAttribute(const std::string& attrKey, int control)
 {
-    std::cout << "========================================================" << std::endl;
-    std::cout << "Select Resource Type" << std::endl;
-    std::cout << "1. Temperature" << std::endl;
-    std::cout << "2. Light" << std::endl;
-    std::cout << "========================================================" << std::endl;
+    const int diff = control == INCREASE ? 1 : - 1;
 
-    switch(processUserInput())
     {
-    case REQUEST_TEMP:
-        resourceUri = "/a/TempSensor";
-        resourceType = "core.TemperatureSensor";
-        break;
-    case REQUEST_LIGHT:
-        resourceUri = "/a/light";
-        resourceType = "core.light";
-        break;
-    default :
-        std::cout << "Invalid input, please try again" << std::endl;
-        return;
+        RCSResourceObject::LockGuard lock(g_resource);
+        auto& attrs = g_resource->getAttributes();
+        attrs[attrKey] = attrs[attrKey].get<int>() + diff;
     }
 
-    try
+    if (control == INCREASE)
     {
-        createResource();
+        std::cout << attrKey << " increased." << std::endl;
     }
-    catch (const PlatformException& e)
+    else
     {
-        std::cout << "Exception in initServer : " << e.what() << std::endl;
+        std::cout << attrKey << " decreased." << std::endl;
     }
-
-    server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
-    server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
-    server->setAttribute(attributeKey, DEFALUT_VALUE);
+    std::cout << "\nCurrent " << attrKey << ": "
+            << g_resource->getAttributeValue(attrKey).get<int>() << std::endl;
 }
 
-void changeTemperature(Control control)
+void runResourceControl(DisplayControlMenuFunc displayMenuFunc, const std::string& attrKey)
 {
-    RCSResourceObject::LockGuard lock(server);
-    if(Control::INCREASE == control)
-    {
-        server->getAttributes()[attributeKey] =
-                server->getAttribute<int>(attributeKey) + 10;
-        std::cout << "\nTemperature increased by 10 degree" << std::endl;
-    }
-    else if(Control::DECREASE == control)
-    {
-        server->getAttributes()[attributeKey] =
-                        server->getAttribute<int>(attributeKey) - 10;
-        std::cout << "\nTemperature Decreased by 10 degree" << std::endl;
-    }
-    std::cout << "\nCurrent Temperature : "
-            << server->getAttributeValue(attributeKey).get<int>() << std::endl;
+    displayMenuFunc();
+    updateAttribute(attrKey, processUserInput(INCREASE, DECREASE));
 }
 
-int processUserInput()
+void runResourceTypeSelection(int resourceMode)
 {
-    int userInput;
-    std::cin >> userInput;
-    if (std::cin.fail())
+    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";
+
+    int resourceType = processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT);
+    DisplayControlMenuFunc displayMenuFunc = nullptr;
+    std::string attrKey;
+
+    switch (resourceType)
     {
-        std::cin.clear();
-        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
-        return -1;
-    }
-    return userInput;
-}
+        case RESOURCE_TEMP:
+            attrKey = "Temperature";
+            initServer("/a/TempSensor", "oic.r.temperaturesensor", attrKey);
 
-int selectPresenceMenu()
-{
-    std::cout << "========================================================" << std::endl;
-    std::cout << "1. Presence On" << std::endl;
-    std::cout << "2. Presence Off" << std::endl;
-    std::cout << "========================================================" << std::endl;
+            displayMenuFunc = displayControlTemperatureMenu;
+            break;
 
-    switch(processUserInput())
-        {
-        case PRESENCE_ON:
-            isPresenceOn = PRESENCE_ON;
-            startPresence(3);
-            return CORRECT_INPUT;
-        case PRESENCE_OFF:
-            isPresenceOn = PRESENCE_OFF;
-            return CORRECT_INPUT;
-        default :
-            std::cout << "Invalid input, please try again" << std::endl;
-            return INCORRECT_INPUT;
-        }
-}
-int selectServerMenu()
-{
-    switch (processUserInput())
+        case RESOURCE_LIGHT:
+            attrKey = "Brightness";
+            initServer("/a/light", "oic.r.light", attrKey);
+
+            displayMenuFunc = displayControlLightMenu;
+            break;
+    }
+
+    if (resourceMode == CUSTOM_SERVER)
     {
-        case DEFALUT_SERVER: // Creation of Resource & Auto control for all requests from Client.
-            initServer();
-            return CORRECT_INPUT;
-
-        case CUSTOM_SERVER:
-            // Creation of Resource & setting get and set handler for handling get and
-            // set request from client in application.
-            initServer();
-
-            server->setGetRequestHandler(requestHandlerForGet);
-            server->setSetRequestHandler(requestHandlerForSet);
-            return CORRECT_INPUT;
-        case STOP :
-            return QUIT;
-
-        default :
-            std::cout << "Invalid input, please try again" << std::endl;
-            return INCORRECT_INPUT;
+        g_resource->setGetRequestHandler(requestHandlerForGet);
+        g_resource->setSetRequestHandler(requestHandlerForSet);
     }
-}
 
-int selectControlTemperatureMenu()
-{
-   switch (processUserInput())
-   {
-       case INCREASE_TEMPERATURE:
-           changeTemperature(Control::INCREASE);
-           return CORRECT_INPUT;
-
-       case DECREASE_TEMPERATURE:
-           changeTemperature(Control::DECREASE);
-           return CORRECT_INPUT;
-
-       case STOP_TEMPERATURE_SENSOR:
-           return QUIT;
-
-       default:
-           std::cout << "Invalid input. Please try again." << std::endl;
-           return INCORRECT_INPUT;
-   }
+    g_currentRun = std::bind(runResourceControl, displayMenuFunc, std::move(attrKey));
 }
 
-int selectControlLightMenu()
+void runResourceModeSelection()
 {
-   switch (processUserInput())
-   {
-       case STOP_LIGHT_SENSOR:
-           return QUIT;
-
-       default:
-           std::cout << "Invalid input. Please try again." << std::endl;
-           return INCORRECT_INPUT;
-   }
+    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 process()
+void runPresenceSelection()
 {
-    while(true)
+    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)
     {
-        int ret = selectPresenceMenu();
-        if(ret == CORRECT_INPUT) break;
+        g_isPresenceStarted = true;
+        startPresence(3);
     }
 
-    while(true)
-    {
-        displayMenu();
-        int ret = selectServerMenu();
+    g_currentRun = runResourceModeSelection;
+}
 
-        if(ret == QUIT) return;
-        if(ret == CORRECT_INPUT) break;
-    }
+int main(void)
+{
+    g_currentRun = runPresenceSelection;
 
-    while(true)
+    while (true)
     {
-        if(resourceType == "core.TemperatureSensor")
+        try
         {
-            displayControlTemperatureMenu();
-            if (selectControlTemperatureMenu() == QUIT) return;
+            g_currentRun();
         }
-        else if(resourceType == "core.light")
+        catch (const std::exception& e)
         {
-            displayControlLightMenu();
-            if (selectControlLightMenu() == QUIT) return;
+            std::cout << e.what() << std::endl;
+        }
+        catch (const CloseApp&)
+        {
+            break;
         }
     }
-}
+    std::cout << "Stopping the server" << std::endl;
 
-int main(void)
-{
-    try
-    {
-        process();
-        server = NULL;
-    }
-    catch (const std::exception& e)
-    {
-        std::cout << "main exception  : " << e.what() << std::endl;
-    }
+    g_resource.reset();
 
-    if(isPresenceOn == PRESENCE_ON)
+    if (g_isPresenceStarted)
     {
-        stopPresence();
+        try
+        {
+            stopPresence();
+        }
+        catch(...)
+        {
+            std::cout << "presence stop fail" << std::endl;
+        }
     }
-    std::cout << "Stopping the Server" << std::endl;
 }
+