4 #include <condition_variable>
11 #include "ocpayload.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->setResponseResult(OC_EH_OK);
90 return OCPlatform::sendResponse(pResponse);
93 OCStackResult propagate()
95 if (m_interestedObservers.size() > 0)
97 shared_ptr<OCResourceResponse> resourceResponse =
98 { make_shared<OCResourceResponse>() };
100 resourceResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE);
102 return OCPlatform::notifyListOfObservers(m_handle,
103 m_interestedObservers,
110 virtual OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request) = 0;
113 OCRepresentation m_representation;
114 vector<Resource *> m_childResources;
115 ObservationIds m_interestedObservers;
118 class BinarySwitchResource : public Resource //oic.r.switch.binary
124 BinarySwitchResource(string uri, vector<string> rt, vector<string> itf)
125 : Resource(uri, rt, itf)
128 m_representation.setValue("value", m_value);
131 void setBinarySwitchRepresentation(OCRepresentation &rep)
134 if (rep.getValue("value", value))
137 m_representation.setValue("value", m_value);
138 cout << "\t\t\t\t" << "value: " << m_value << endl;
144 OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request)
146 cout << "\tIn Server Binaryswitch entity handler:\n";
147 OCEntityHandlerResult ehResult = OC_EH_ERROR;
151 // Get the request type and request flag
152 string requestType = request->getRequestType();
153 int requestFlag = request->getRequestHandlerFlag();
155 if (requestFlag & RequestHandlerFlag::RequestFlag)
157 cout << "\t\trequestFlag : Request\n";
159 // If the request type is GET
160 if (requestType == "GET")
162 cout << "\t\t\trequestType : GET\n";
163 if (OC_STACK_OK == sendRepresentation(request))
168 else if (requestType == "PUT")
170 cout << "\t\t\trequestType : PUT\n";
171 // PUT request operations
173 else if (requestType == "POST")
175 cout << "\t\t\trequestType : POST\n";
176 // POST request operations
177 OCRepresentation rep = request->getResourceRepresentation();
178 setBinarySwitchRepresentation(rep);
180 if (OC_STACK_OK == sendRepresentation(request))
185 else if (requestType == "DELETE")
187 cout << "\t\t\trequestType : DELETE\n";
188 // DELETE request operations
192 if (requestFlag & RequestHandlerFlag::ObserverFlag)
194 cout << "\t\trequestFlag : Observer\n";
196 ObservationInfo observationInfo = request->getObservationInfo();
197 if (ObserveAction::ObserveRegister == observationInfo.action)
199 m_interestedObservers.push_back(observationInfo.obsId);
201 else if (ObserveAction::ObserveUnregister == observationInfo.action)
203 m_interestedObservers.erase(remove(
204 m_interestedObservers.begin(),
205 m_interestedObservers.end(),
206 observationInfo.obsId),
207 m_interestedObservers.end());
213 cout << "Request invalid" << endl;
220 class TemperatureResource : public Resource //oic.r.temperature
228 TemperatureResource(string uri, vector<string> rt, vector<string> itf)
229 : Resource(uri, rt, itf)
234 m_representation.setValue("temperature", m_temperature);
235 m_representation.setValue("range", m_range);
236 m_representation.setValue("units", m_units);
239 void setTemperatureRepresentation(OCRepresentation &rep)
245 if (rep.getValue("temperature", temperature) &&
246 rep.getValue("range", range) &&
247 rep.getValue("units", units))
249 m_temperature = temperature;
252 m_representation.setValue("temperature", m_temperature);
253 m_representation.setValue("range", m_range);
254 m_representation.setValue("units", m_units);
255 cout << "\t\t\t\t" << "temperature: " << m_temperature << endl;
256 cout << "\t\t\t\t" << "range: " << m_range << endl;
257 cout << "\t\t\t\t" << "units: " << m_units << endl;
263 OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request)
265 cout << "\tIn Server Temperature entity handler:\n";
266 OCEntityHandlerResult ehResult = OC_EH_ERROR;
270 // Get the request type and request flag
271 string requestType = request->getRequestType();
272 int requestFlag = request->getRequestHandlerFlag();
274 if (requestFlag & RequestHandlerFlag::RequestFlag)
276 cout << "\t\trequestFlag : Request\n";
278 // If the request type is GET
279 if (requestType == "GET")
281 cout << "\t\t\trequestType : GET\n";
282 if (OC_STACK_OK == sendRepresentation(request))
287 else if (requestType == "PUT")
289 cout << "\t\t\trequestType : PUT\n";
290 // PUT requeist operations
292 else if (requestType == "POST")
294 cout << "\t\t\trequestType : POST\n";
295 // POST request operations
296 OCRepresentation rep = request->getResourceRepresentation();
297 setTemperatureRepresentation(rep);
299 if (OC_STACK_OK == sendRepresentation(request))
304 else if (requestType == "DELETE")
306 cout << "\t\t\trequestType : DELETE\n";
307 // DELETE request operations
311 if (requestFlag & RequestHandlerFlag::ObserverFlag)
313 cout << "\t\trequestFlag : Observer\n";
315 ObservationInfo observationInfo = request->getObservationInfo();
316 if (ObserveAction::ObserveRegister == observationInfo.action)
318 m_interestedObservers.push_back(observationInfo.obsId);
320 else if (ObserveAction::ObserveUnregister == observationInfo.action)
322 m_interestedObservers.erase(remove(
323 m_interestedObservers.begin(),
324 m_interestedObservers.end(),
325 observationInfo.obsId),
326 m_interestedObservers.end());
332 cout << "Request invalid" << endl;
339 class AirConditionerResource : public Resource // oic.d.airconditioner
344 AirConditionerResource(string uri, vector<string> rt, vector<string> itf)
345 : Resource(uri, rt, itf)
350 OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request)
352 cout << "\tIn Server Airconditioner entity handler:\n";
353 OCEntityHandlerResult ehResult = OC_EH_ERROR;
357 // Get the request type and request flag
358 string requestType = request->getRequestType();
359 int requestFlag = request->getRequestHandlerFlag();
361 if (requestFlag & RequestHandlerFlag::RequestFlag)
363 cout << "\t\trequestFlag : Request\n";
365 // If the request type is GET
366 if (requestType == "GET")
368 cout << "\t\t\trequestType : GET\n";
369 string findRes = request->getQueryParameters().find("if")->second;
370 if (findRes.compare(LINK_INTERFACE) == 0)
372 if (OC_STACK_OK == sendRepresentation(request))
379 ehResult = OC_EH_FORBIDDEN;
382 else if (requestType == "PUT")
384 cout << "\t\t\trequestType : PUT\n";
385 // Call these functions to prepare the response for child resources and
386 // then send the final response using sendRoomResponse function
389 for (auto it = m_childResources.begin();
390 it != m_childResources.end(); it++)
392 (*it)->entityHandler(request);
395 if (OC_STACK_OK == sendRepresentation(request))
401 else if (requestType == "POST")
403 // POST request operations
405 else if (requestType == "DELETE")
407 // DELETE request operations
411 if (requestFlag & RequestHandlerFlag::ObserverFlag)
413 cout << "\t\trequestFlag : Observer\n";
418 cout << "Request invalid" << endl;
425 condition_variable g_callbackLock;
427 string g_accesstoken;
429 void onPublish(const OCRepresentation &, const int &eCode)
431 cout << "Publish resource response received, code: " << eCode << endl;
433 g_callbackLock.notify_all();
436 void printRepresentation(OCRepresentation rep)
438 for (auto itr = rep.begin(); itr != rep.end(); ++itr)
440 cout << "\t" << itr->attrname() << ":\t" << itr->getValueToString() << endl;
441 if (itr->type() == AttributeType::Vector)
443 switch (itr->base_type())
445 case AttributeType::OCRepresentation:
446 for (auto itr2 : (*itr).getValue<vector<OCRepresentation> >())
448 printRepresentation(itr2);
452 case AttributeType::Integer:
453 for (auto itr2 : (*itr).getValue<vector<int> >())
455 cout << "\t\t" << itr2 << endl;
459 case AttributeType::String:
460 for (auto itr2 : (*itr).getValue<vector<string> >())
462 cout << "\t\t" << itr2 << endl;
467 cout << "Unhandled base type " << itr->base_type() << endl;
471 else if (itr->type() == AttributeType::OCRepresentation)
473 printRepresentation((*itr).getValue<OCRepresentation>());
478 void handleLoginoutCB(const HeaderOptions &,
479 const OCRepresentation &rep, const int ecode)
481 cout << "Auth response received code: " << ecode << endl;
483 if (rep.getPayload() != NULL)
485 printRepresentation(rep);
490 g_accesstoken = rep.getValueToString("accesstoken");
492 g_uid = rep.getValueToString("uid");
495 g_callbackLock.notify_all();
498 static FILE *client_open(const char * /*path*/, const char *mode)
500 return fopen("./aircon_controlee.dat", mode);
503 OCStackResult SetDeviceInfo()
505 OCStackResult result = OC_STACK_ERROR;
507 OCResourceHandle handle = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI);
511 cout << "Failed to find resource " << OC_RSRVD_DEVICE_URI << endl;
515 result = OCBindResourceTypeToResource(handle, "oic.d.airconditioner");
517 if (result != OC_STACK_OK)
519 cout << "Failed to add device type" << endl;
523 result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, "FAC_2016");
525 if (result != OC_STACK_OK)
527 cout << "Failed to set device name" << endl;
531 result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_PROTOCOL_INDEPENDENT_ID,
532 "d7d2b492-83ac-4783-9dcc-b1b54587ebed");
534 if (result != OC_STACK_OK)
536 cout << "Failed to set piid" << endl;
543 int main(int argc, char *argv[])
545 if (argc != 4 && argc != 5)
547 cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and publish resources"
549 cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and publish resources" <<
554 OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink };
560 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
561 0, // Uses randomly available port
562 QualityOfService::LowQos,
566 OCPlatform::Configure(cfg);
568 OCStackResult result = OC_STACK_ERROR;
570 string host = "coap+tcp://";
573 OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(host,
577 unique_lock<mutex> lock(blocker);
581 accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
582 g_callbackLock.wait(lock);
586 accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
587 g_callbackLock.wait(lock);
588 accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
589 g_callbackLock.wait(lock);
593 cout << "Registering resources to platform..." << endl;
595 AirConditionerResource airConditioner("/sec/aircon/0", { "x.com.samsung.da.device" }, { DEFAULT_INTERFACE, BATCH_INTERFACE, LINK_INTERFACE });
597 BinarySwitchResource binarySwitch("/power/0", { "oic.r.switch.binary" }, { DEFAULT_INTERFACE });
599 TemperatureResource temperature("/temperature/0", { "oic.r.temperature" }, { DEFAULT_INTERFACE });
601 string uri = airConditioner.getResourceUri();
602 string rt = airConditioner.getResourceType()[0];
603 string itf = airConditioner.getInterfaces()[0];
605 result = OCPlatform::registerResource(airConditioner.m_handle,
609 bind(&AirConditionerResource::entityHandler
610 , &airConditioner, placeholders::_1),
613 if (result != OC_STACK_OK)
615 cout << "Resource registration was unsuccessful" << endl;
619 itf = airConditioner.getInterfaces()[1];
620 result = OCPlatform::bindInterfaceToResource(airConditioner.m_handle, itf);
622 if (result != OC_STACK_OK)
624 cout << "Binding second interface was unsuccessful" << endl;
628 itf = airConditioner.getInterfaces()[2];
629 result = OCPlatform::bindInterfaceToResource(airConditioner.m_handle, itf);
631 if (result != OC_STACK_OK)
633 cout << "Binding third interface was unsuccessful" << endl;
637 uri = binarySwitch.getResourceUri();
638 rt = binarySwitch.getResourceType()[0];
639 itf = binarySwitch.getInterfaces()[0];
641 result = OCPlatform::registerResource(binarySwitch.m_handle,
645 bind(&BinarySwitchResource::entityHandler
646 , &binarySwitch, placeholders::_1),
649 if (result != OC_STACK_OK)
654 uri = temperature.getResourceUri();
655 rt = temperature.getResourceType()[0];
656 itf = temperature.getInterfaces()[0];
658 result = OCPlatform::registerResource(temperature.m_handle,
662 bind(&TemperatureResource::entityHandler
663 , &temperature, placeholders::_1),
666 if (result != OC_STACK_OK)
671 result = airConditioner.addChildResource(&binarySwitch);
673 if (result != OC_STACK_OK)
678 result = airConditioner.addChildResource(&temperature);
680 if (result != OC_STACK_OK)
685 cout << "Publishing resources to cloud ";
687 result = SetDeviceInfo();
689 if (result != OC_STACK_OK)
694 ResourceHandles resourceHandles;
696 result = RDClient::Instance().publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP,
700 cout << " result: " << result << " Waiting Publish default resource response from cloud" << endl;
702 resourceHandles.push_back(airConditioner.m_handle);
704 result = RDClient::Instance().publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP,
708 cout << " result: " << result << " Waiting Publish user resource response from cloud" << endl;
710 g_callbackLock.wait(lock);
713 cout << "PUT 1/0 to turn on/off air conditioner for observe testing, q to terminate" << endl;
720 OCRepresentation rep;
725 rep.setValue(string("value"), true);
726 binarySwitch.setBinarySwitchRepresentation(rep);
730 rep.setValue(string("value"), false);
731 binarySwitch.setBinarySwitchRepresentation(rep);