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 int main(int argc, char *argv[])
505 if (argc != 4 && argc != 5)
507 cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and publish resources"
509 cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and publish resources" <<
514 OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink };
520 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
521 0, // Uses randomly available port
522 QualityOfService::LowQos,
526 OCPlatform::Configure(cfg);
528 OCStackResult result = OC_STACK_ERROR;
530 string host = "coap+tcp://";
533 OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(host,
537 unique_lock<mutex> lock(blocker);
541 accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
542 g_callbackLock.wait(lock);
546 accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
547 g_callbackLock.wait(lock);
548 accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
549 g_callbackLock.wait(lock);
553 cout << "Registering resources to platform..." << endl;
555 AirConditionerResource airConditioner("/sec/aircon/0", { "x.com.samsung.da.device" }, { DEFAULT_INTERFACE, BATCH_INTERFACE, LINK_INTERFACE });
557 BinarySwitchResource binarySwitch("/power/0", { "oic.r.switch.binary" }, { DEFAULT_INTERFACE });
559 TemperatureResource temperature("/temperature/0", { "oic.r.temperature" }, { DEFAULT_INTERFACE });
561 string uri = airConditioner.getResourceUri();
562 string rt = airConditioner.getResourceType()[0];
563 string itf = airConditioner.getInterfaces()[0];
565 result = OCPlatform::registerResource(airConditioner.m_handle,
569 bind(&AirConditionerResource::entityHandler
570 , &airConditioner, placeholders::_1),
573 if (result != OC_STACK_OK)
575 cout << "Resource registration was unsuccessful" << endl;
579 itf = airConditioner.getInterfaces()[1];
580 result = OCPlatform::bindInterfaceToResource(airConditioner.m_handle, itf);
582 if (result != OC_STACK_OK)
584 cout << "Binding second interface was unsuccessful" << endl;
588 itf = airConditioner.getInterfaces()[2];
589 result = OCPlatform::bindInterfaceToResource(airConditioner.m_handle, itf);
591 if (result != OC_STACK_OK)
593 cout << "Binding third interface was unsuccessful" << endl;
597 uri = binarySwitch.getResourceUri();
598 rt = binarySwitch.getResourceType()[0];
599 itf = binarySwitch.getInterfaces()[0];
601 result = OCPlatform::registerResource(binarySwitch.m_handle,
605 bind(&BinarySwitchResource::entityHandler
606 , &binarySwitch, placeholders::_1),
609 uri = temperature.getResourceUri();
610 rt = temperature.getResourceType()[0];
611 itf = temperature.getInterfaces()[0];
613 result = OCPlatform::registerResource(temperature.m_handle,
617 bind(&TemperatureResource::entityHandler
618 , &temperature, placeholders::_1),
621 result = airConditioner.addChildResource(&binarySwitch);
623 result = airConditioner.addChildResource(&temperature);
625 cout << "Publishing resources to cloud ";
628 ResourceHandles resourceHandles;
630 OCDeviceInfo devInfoAirConditioner;
631 OCStringLL deviceType;
633 deviceType.value = "oic.d.airconditioner";
634 deviceType.next = NULL;
635 devInfoAirConditioner.deviceName = "FAC_2016";
636 devInfoAirConditioner.types = &deviceType;
637 devInfoAirConditioner.specVersion = NULL;
638 devInfoAirConditioner.dataModelVersions = NULL;
640 OCPlatform::registerDeviceInfo(devInfoAirConditioner);
642 result = RDClient::Instance().publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP,
646 cout << " result: " << result << " Waiting Publish default resource response from cloud" << endl;
648 resourceHandles.push_back(airConditioner.m_handle);
650 result = RDClient::Instance().publishResourceToRD(host, OCConnectivityType::CT_ADAPTER_TCP,
654 cout << " result: " << result << " Waiting Publish user resource response from cloud" << endl;
656 g_callbackLock.wait(lock);
659 cout << "PUT 1/0 to turn on/off air conditioner for observe testing, q to terminate" << endl;
666 OCRepresentation rep;
671 rep.setValue(string("value"), true);
672 binarySwitch.setBinarySwitchRepresentation(rep);
676 rep.setValue(string("value"), false);
677 binarySwitch.setBinarySwitchRepresentation(rep);