*
******************************************************************/
-#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;
+ }
}
}
-