1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 /// This sample provides steps to define an interface for a resource
23 /// (properties and methods) and host this resource on the server.
26 #include "iotivity_config.h"
34 #include <condition_variable>
36 #include "OCPlatform.h"
46 #define numPresenceResources (2)
48 // Forward declaring the entityHandler
49 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request);
51 /// This class represents a single resource named 'lightResource'. This resource has
52 /// two simple properties named 'state' and 'power'
57 /// Access this property from a TB client
60 std::string m_lightUri;
61 std::string m_lightUri2;
62 std::string m_lightUri3;
63 OCResourceHandle m_resourceHandle;
64 OCResourceHandle m_resourceHandle2;
65 OCResourceHandle m_resourceHandle3;
69 LightResource(): m_state(false), m_power(0), m_lightUri("/a/light"),
70 m_lightUri2("/a/light2"),m_lightUri3("/a/light3") {}
72 /* Note that this does not need to be a member function: for classes you do not have
73 access to, you can accomplish this with a free function: */
75 /// This function internally calls registerResource API.
78 std::string resourceURI = m_lightUri; // URI of the resource
79 std::string resourceTypeName = "core.light"; // resource type name.
80 std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
82 // OCResourceProperty is defined ocstack.h
83 uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
85 // This will internally create and register the resource.
86 OCStackResult result = OCPlatform::registerResource(
87 m_resourceHandle, resourceURI, resourceTypeName,
88 resourceInterface, &entityHandler, resourceProperty);
90 if (OC_STACK_OK != result)
92 cout << "Resource creation was unsuccessful\n";
96 /// This function internally calls registerResource API.
97 void createResource2()
99 std::string resourceURI = m_lightUri2; // URI of the resource
100 std::string resourceTypeName = "core.light"; // resource type name. In this case, it is light
101 std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
103 // OCResourceProperty is defined ocstack.h
104 uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
106 // This will internally create and register the resource.
107 OCStackResult result = OCPlatform::registerResource(
108 m_resourceHandle2, resourceURI, resourceTypeName,
109 resourceInterface, &entityHandler, resourceProperty);
111 if (OC_STACK_OK != result)
113 cout << "Resource creation was unsuccessful\n";
117 void createResource3()
119 std::string resourceURI = m_lightUri3; // URI of the resource
120 std::string resourceTypeName = "core.light";
121 std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
123 // OCResourceProperty is defined ocstack.h
124 uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
126 // This will internally create and register the resource.
127 OCStackResult result = OCPlatform::registerResource(
128 m_resourceHandle3, resourceURI, resourceTypeName,
129 resourceInterface, &entityHandler, resourceProperty);
131 if (OC_STACK_OK != result)
133 cout << "Resource creation was unsuccessful\n";
137 OCResourceHandle getHandle()
139 return m_resourceHandle;
142 void addType(const std::string& type) const
144 OCStackResult result = OC::OCPlatform::bindTypeToResource(m_resourceHandle, type);
145 if (OC_STACK_OK != result)
147 cout << "Binding TypeName to Resource was unsuccessful\n";
151 void addInterface(const std::string& iface) const
153 OCStackResult result = OC::OCPlatform::bindInterfaceToResource(m_resourceHandle, iface);
154 if (OC_STACK_OK != result)
156 cout << "Binding TypeName to Resource was unsuccessful\n";
162 void createPresenceResources()
164 std::array<std::string, numPresenceResources> resourceURI { {
167 std::array<std::string, numPresenceResources> resourceTypeName { {
171 std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
172 OCResourceHandle handle;
173 // OCResourceProperty is defined ocstack.h
174 uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
176 // This will internally create and register the resource.
177 OCStackResult result = OC_STACK_OK;
178 for(int i=0; i<numPresenceResources; i++)
180 result = OCPlatform::registerResource(handle,
181 resourceURI.at(i), resourceTypeName.at(i), resourceInterface,
182 &entityHandler, resourceProperty);
183 if (result != OC_STACK_OK)
185 cout << "Resource creation was unsuccessful with resource URI "
186 << resourceURI.at(i);
191 // Create the instance of the resource class (in this case instance of class 'LightResource').
192 LightResource myLightResource;
194 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> /*request*/)
196 cout << "\tIn Server CPP entity handler:\n";
202 // Create PlatformConfig object
204 OC::ServiceType::InProc,
205 OC::ModeType::Server,
206 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
207 0, // Uses randomly available port
208 OC::QualityOfService::LowQos
211 OCPlatform::Configure(cfg);
214 using namespace OC::OCPlatform;
215 // Time to Live is 30 seconds
218 // Invoke createResource function of class light.
219 myLightResource.createResource();
220 std :: cout << "Creating first resource of type \"core.light\"" << std :: endl;
222 std :: cout << "Will start creating/deleting resources for presence in 10 seconds.\n";
226 std :: cout << "\nCreating the second resource of type \"core.light\"" << std :: endl;
229 myLightResource.createResource2();
231 std :: cout << "Stopping presence\n" << std :: endl;
235 std :: cout << "Restarting presence\n" << std :: endl;
240 std :: cout << "Creating a third resource of type \"core.light\"\n" << std :: endl;
243 myLightResource.createResource3();
245 std :: cout << "Creating two non-operational resources.\"\n" << std :: endl;
248 createPresenceResources();
250 // A condition variable will free the mutex it is given, then do a non-
251 // intensive block until 'notify' is called on it. In this case, since we
252 // don't ever call cv.notify, this should be a non-processor intensive version
255 std::condition_variable cv;
256 std::unique_lock<std::mutex> lock(blocker);
259 catch(OCException& e)
261 oclog() << "Exception in main: "<< e.what();
264 // No explicit call to stop the platform.
265 // When OCPlatform destructor is invoked, internally we do platform cleanup