4 #include <condition_variable>
11 #include "ocpayload.h"
12 #include "rd_client.h"
15 #include <OCPlatform.h>
23 OCResourceHandle m_handle;
24 Resource(string uri, vector<string> rt, vector<string> itf)
26 m_representation.setUri(uri);
27 m_representation.setResourceTypes(rt);
28 m_representation.setResourceInterfaces(itf);
31 string getResourceUri()
33 return m_representation.getUri();
36 vector<string> getResourceType()
38 return m_representation.getResourceTypes();
41 vector<string> getInterfaces()
43 return m_representation.getResourceInterfaces();
46 OCRepresentation getRepresentation(void)
48 m_representation.clearChildren();
49 for (auto it = m_childResources.begin(); it != m_childResources.end(); it++)
51 m_representation.addChild((*it)->getRepresentation());
53 return m_representation;
56 OCStackResult addChildResource(Resource *childResource)
58 m_childResources.push_back(childResource);
59 return OCPlatform::bindResource(m_handle, childResource->m_handle);
62 OCStackResult sendRepresentation(shared_ptr<OCResourceRequest> pRequest)
64 auto pResponse = make_shared<OC::OCResourceResponse>();
65 pResponse->setRequestHandle(pRequest->getRequestHandle());
66 pResponse->setResourceHandle(pRequest->getResourceHandle());
68 // Check for query params (if any)
69 QueryParamsMap queryParamsMap = pRequest->getQueryParameters();
71 cout << "\t\t\tquery params: \n";
72 for (auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)
74 cout << "\t\t\t\t" << it->first << ":" << it->second << endl;
77 auto findRes = queryParamsMap.find("if");
79 if (findRes != queryParamsMap.end())
81 pResponse->setResourceRepresentation(getRepresentation(), findRes->second);
85 pResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE);
88 pResponse->setErrorCode(200);
89 pResponse->setResponseResult(OC_EH_OK);
91 return OCPlatform::sendResponse(pResponse);
94 OCStackResult propagate()
96 if (m_interestedObservers.size() > 0)
98 shared_ptr<OCResourceResponse> resourceResponse =
99 { make_shared<OCResourceResponse>() };
101 resourceResponse->setErrorCode(200);
102 resourceResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE);
104 return OCPlatform::notifyListOfObservers(m_handle,
105 m_interestedObservers,
112 virtual OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request) = 0;
115 OCRepresentation m_representation;
116 vector<Resource *> m_childResources;
117 ObservationIds m_interestedObservers;
120 class BinarySwitchResource : public Resource //oic.r.switch.binary
126 BinarySwitchResource(string uri, vector<string> rt, vector<string> itf)
127 : Resource(uri, rt, itf)
130 m_representation.setValue("value", m_value);
133 void setBinarySwitchRepresentation(OCRepresentation &rep)
136 if (rep.getValue("value", value))
139 m_representation.setValue("value", m_value);
140 cout << "\t\t\t\t" << "value: " << m_value << endl;
146 OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request)
148 cout << "\tIn Server Binaryswitch entity handler:\n";
149 OCEntityHandlerResult ehResult = OC_EH_ERROR;
153 // Get the request type and request flag
154 string requestType = request->getRequestType();
155 int requestFlag = request->getRequestHandlerFlag();
157 if (requestFlag & RequestHandlerFlag::RequestFlag)
159 cout << "\t\trequestFlag : Request\n";
161 // If the request type is GET
162 if (requestType == "GET")
164 cout << "\t\t\trequestType : GET\n";
165 if (OC_STACK_OK == sendRepresentation(request))
170 else if (requestType == "PUT")
172 cout << "\t\t\trequestType : PUT\n";
173 // PUT request operations
175 else if (requestType == "POST")
177 cout << "\t\t\trequestType : POST\n";
178 // POST request operations
179 OCRepresentation rep = request->getResourceRepresentation();
180 setBinarySwitchRepresentation(rep);
182 if (OC_STACK_OK == sendRepresentation(request))
187 else if (requestType == "DELETE")
189 cout << "\t\t\trequestType : DELETE\n";
190 // DELETE request operations
194 if (requestFlag & RequestHandlerFlag::ObserverFlag)
196 cout << "\t\trequestFlag : Observer\n";
198 ObservationInfo observationInfo = request->getObservationInfo();
199 if (ObserveAction::ObserveRegister == observationInfo.action)
201 m_interestedObservers.push_back(observationInfo.obsId);
203 else if (ObserveAction::ObserveUnregister == observationInfo.action)
205 m_interestedObservers.erase(remove(
206 m_interestedObservers.begin(),
207 m_interestedObservers.end(),
208 observationInfo.obsId),
209 m_interestedObservers.end());
215 cout << "Request invalid" << endl;
222 class TemperatureResource : public Resource //oic.r.temperature
230 TemperatureResource(string uri, vector<string> rt, vector<string> itf)
231 : Resource(uri, rt, itf)
236 m_representation.setValue("temperature", m_temperature);
237 m_representation.setValue("range", m_range);
238 m_representation.setValue("units", m_units);
241 void setTemperatureRepresentation(OCRepresentation &rep)
247 if (rep.getValue("temperature", temperature) &&
248 rep.getValue("range", range) &&
249 rep.getValue("units", units))
251 m_temperature = temperature;
254 m_representation.setValue("temperature", m_temperature);
255 m_representation.setValue("range", m_range);
256 m_representation.setValue("units", m_units);
257 cout << "\t\t\t\t" << "temperature: " << m_temperature << endl;
258 cout << "\t\t\t\t" << "range: " << m_range << endl;
259 cout << "\t\t\t\t" << "units: " << m_units << endl;
265 OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request)
267 cout << "\tIn Server Temperature entity handler:\n";
268 OCEntityHandlerResult ehResult = OC_EH_ERROR;
272 // Get the request type and request flag
273 string requestType = request->getRequestType();
274 int requestFlag = request->getRequestHandlerFlag();
276 if (requestFlag & RequestHandlerFlag::RequestFlag)
278 cout << "\t\trequestFlag : Request\n";
280 // If the request type is GET
281 if (requestType == "GET")
283 cout << "\t\t\trequestType : GET\n";
284 if (OC_STACK_OK == sendRepresentation(request))
289 else if (requestType == "PUT")
291 cout << "\t\t\trequestType : PUT\n";
292 // PUT requeist operations
294 else if (requestType == "POST")
296 cout << "\t\t\trequestType : POST\n";
297 // POST request operations
298 OCRepresentation rep = request->getResourceRepresentation();
299 setTemperatureRepresentation(rep);
301 if (OC_STACK_OK == sendRepresentation(request))
306 else if (requestType == "DELETE")
308 cout << "\t\t\trequestType : DELETE\n";
309 // DELETE request operations
313 if (requestFlag & RequestHandlerFlag::ObserverFlag)
315 cout << "\t\trequestFlag : Observer\n";
317 ObservationInfo observationInfo = request->getObservationInfo();
318 if (ObserveAction::ObserveRegister == observationInfo.action)
320 m_interestedObservers.push_back(observationInfo.obsId);
322 else if (ObserveAction::ObserveUnregister == observationInfo.action)
324 m_interestedObservers.erase(remove(
325 m_interestedObservers.begin(),
326 m_interestedObservers.end(),
327 observationInfo.obsId),
328 m_interestedObservers.end());
334 cout << "Request invalid" << endl;
341 class AirConditionerResource : public Resource // oic.d.airconditioner
346 AirConditionerResource(string uri, vector<string> rt, vector<string> itf)
347 : Resource(uri, rt, itf)
352 OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request)
354 cout << "\tIn Server Airconditioner entity handler:\n";
355 OCEntityHandlerResult ehResult = OC_EH_ERROR;
359 // Get the request type and request flag
360 string requestType = request->getRequestType();
361 int requestFlag = request->getRequestHandlerFlag();
363 if (requestFlag & RequestHandlerFlag::RequestFlag)
365 cout << "\t\trequestFlag : Request\n";
367 // If the request type is GET
368 if (requestType == "GET")
370 cout << "\t\t\trequestType : GET\n";
371 string findRes = request->getQueryParameters().find("if")->second;
372 if (findRes.compare(LINK_INTERFACE) == 0)
374 if (OC_STACK_OK == sendRepresentation(request))
381 ehResult = OC_EH_FORBIDDEN;
384 else if (requestType == "PUT")
386 cout << "\t\t\trequestType : PUT\n";
387 // Call these functions to prepare the response for child resources and
388 // then send the final response using sendRoomResponse function
391 for (auto it = m_childResources.begin();
392 it != m_childResources.end(); it++)
394 (*it)->entityHandler(request);
397 if (OC_STACK_OK == sendRepresentation(request))
403 else if (requestType == "POST")
405 // POST request operations
407 else if (requestType == "DELETE")
409 // DELETE request operations
413 if (requestFlag & RequestHandlerFlag::ObserverFlag)
415 cout << "\t\trequestFlag : Observer\n";
420 cout << "Request invalid" << endl;
427 condition_variable g_callbackLock;
429 string g_accesstoken;
431 void onPublish(const OCRepresentation &, const int &eCode)
433 cout << "Publish resource response received, code: " << eCode << endl;
435 g_callbackLock.notify_all();
438 void printRepresentation(OCRepresentation rep)
440 for (auto itr = rep.begin(); itr != rep.end(); ++itr)
442 cout << "\t" << itr->attrname() << ":\t" << itr->getValueToString() << endl;
443 if (itr->type() == AttributeType::Vector)
445 switch (itr->base_type())
447 case AttributeType::OCRepresentation:
448 for (auto itr2 : (*itr).getValue<vector<OCRepresentation> >())
450 printRepresentation(itr2);
454 case AttributeType::Integer:
455 for (auto itr2 : (*itr).getValue<vector<int> >())
457 cout << "\t\t" << itr2 << endl;
461 case AttributeType::String:
462 for (auto itr2 : (*itr).getValue<vector<string> >())
464 cout << "\t\t" << itr2 << endl;
469 cout << "Unhandled base type " << itr->base_type() << endl;
473 else if (itr->type() == AttributeType::OCRepresentation)
475 printRepresentation((*itr).getValue<OCRepresentation>());
480 void handleLoginoutCB(const HeaderOptions &,
481 const OCRepresentation &rep, const int ecode)
483 cout << "Auth response received code: " << ecode << endl;
485 if (rep.getPayload() != NULL)
487 printRepresentation(rep);
492 g_accesstoken = rep.getValueToString("accesstoken");
494 g_uid = rep.getValueToString("uid");
497 g_callbackLock.notify_all();
500 static FILE *client_open(const char * /*path*/, const char *mode)
502 return fopen("./aircon_controlee.dat", mode);
505 int main(int argc, char *argv[])
507 if (argc != 4 && argc != 5)
509 cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and publish resources"
511 cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and publish resources" <<
516 OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink };
522 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
523 0, // Uses randomly available port
524 QualityOfService::LowQos,
528 OCPlatform::Configure(cfg);
530 OCStackResult result = OC_STACK_ERROR;
532 string host = "coap+tcp://";
535 OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(host,
539 unique_lock<mutex> lock(blocker);
543 accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
544 g_callbackLock.wait(lock);
548 accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
549 g_callbackLock.wait(lock);
550 accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
551 g_callbackLock.wait(lock);
555 cout << "Registering resources to platform..." << endl;
557 AirConditionerResource airConditioner("/sec/aircon/0", { "x.com.samsung.da.device" }, { DEFAULT_INTERFACE, BATCH_INTERFACE, LINK_INTERFACE });
559 BinarySwitchResource binarySwitch("/power/0", { "oic.r.switch.binary" }, { DEFAULT_INTERFACE });
561 TemperatureResource temperature("/temperature/0", { "oic.r.temperature" }, { DEFAULT_INTERFACE });
563 string uri = airConditioner.getResourceUri();
564 string rt = airConditioner.getResourceType()[0];
565 string itf = airConditioner.getInterfaces()[0];
567 result = OCPlatform::registerResource(airConditioner.m_handle,
571 bind(&AirConditionerResource::entityHandler
572 , &airConditioner, placeholders::_1),
575 if (result != OC_STACK_OK)
577 cout << "Resource registration was unsuccessful" << endl;
581 itf = airConditioner.getInterfaces()[1];
582 result = OCPlatform::bindInterfaceToResource(airConditioner.m_handle, itf);
584 if (result != OC_STACK_OK)
586 cout << "Binding second interface was unsuccessful" << endl;
590 itf = airConditioner.getInterfaces()[2];
591 result = OCPlatform::bindInterfaceToResource(airConditioner.m_handle, itf);
593 if (result != OC_STACK_OK)
595 cout << "Binding third interface was unsuccessful" << endl;
599 uri = binarySwitch.getResourceUri();
600 rt = binarySwitch.getResourceType()[0];
601 itf = binarySwitch.getInterfaces()[0];
603 result = OCPlatform::registerResource(binarySwitch.m_handle,
607 bind(&BinarySwitchResource::entityHandler
608 , &binarySwitch, placeholders::_1),
611 uri = temperature.getResourceUri();
612 rt = temperature.getResourceType()[0];
613 itf = temperature.getInterfaces()[0];
615 result = OCPlatform::registerResource(temperature.m_handle,
619 bind(&TemperatureResource::entityHandler
620 , &temperature, placeholders::_1),
623 result = airConditioner.addChildResource(&binarySwitch);
625 result = airConditioner.addChildResource(&temperature);
627 cout << "Publishing resources to cloud ";
630 ResourceHandles resourceHandles;
632 OCDeviceInfo devInfoAirConditioner;
633 OCStringLL deviceType;
635 deviceType.value = "oic.d.airconditioner";
636 deviceType.next = NULL;
637 devInfoAirConditioner.deviceName = "FAC_2016";
638 devInfoAirConditioner.types = &deviceType;
639 devInfoAirConditioner.specVersion = NULL;
640 devInfoAirConditioner.dataModelVersions = NULL;
642 OCPlatform::registerDeviceInfo(devInfoAirConditioner);
644 result = OCPlatform::publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP,
648 cout << " result: " << result << " Waiting Publish default resource response from cloud" << endl;
650 resourceHandles.push_back(airConditioner.m_handle);
652 result = OCPlatform::publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP,
656 cout << " result: " << result << " Waiting Publish user resource response from cloud" << endl;
658 g_callbackLock.wait(lock);
661 cout << "PUT 1/0 to turn on/off air conditioner for observe testing, q to terminate" << endl;
668 OCRepresentation rep;
673 rep.setValue(string("value"), true);
674 binarySwitch.setBinarySwitchRepresentation(rep);
678 rep.setValue(string("value"), false);
679 binarySwitch.setBinarySwitchRepresentation(rep);