4 #include <condition_variable>
11 #include "ocpayload.h"
14 #include <OCPlatform.h>
16 #define maxSequenceNumber 0xFFFFFF
22 condition_variable g_callbackLock;
27 OC::OCResource::Ptr g_binaryswitchResource;
29 void printRepresentation(OCRepresentation rep)
31 for (auto itr = rep.begin(); itr != rep.end(); ++itr)
33 cout << "\t" << itr->attrname() << ":\t" << itr->getValueToString() << endl;
34 if (itr->type() == AttributeType::Vector)
36 switch (itr->base_type())
38 case AttributeType::OCRepresentation:
39 for (auto itr2 : (*itr).getValue<vector<OCRepresentation> >())
41 printRepresentation(itr2);
45 case AttributeType::Integer:
46 for (auto itr2 : (*itr).getValue<vector<int> >())
48 cout << "\t\t" << itr2 << endl;
52 case AttributeType::String:
53 for (auto itr2 : (*itr).getValue<vector<string> >())
55 cout << "\t\t" << itr2 << endl;
60 cout << "Unhandled base type " << itr->base_type() << endl;
64 else if (itr->type() == AttributeType::OCRepresentation)
66 printRepresentation((*itr).getValue<OCRepresentation>());
71 void handleLoginoutCB(const HeaderOptions &,
72 const OCRepresentation &rep, const int ecode)
74 cout << "Login/out response received code: " << ecode << endl;
76 if (rep.getPayload() != NULL)
78 printRepresentation(rep);
83 g_accesstoken = rep.getValueToString("accesstoken");
85 g_uid = rep.getValueToString("uid");
88 g_callbackLock.notify_all();
91 void printResource(const OCRepresentation &rep)
93 cout << "URI: " << rep.getUri() << endl;
95 vector<string> rt = rep.getResourceTypes();
96 for (auto it = rt.begin(); it != rt.end(); it++)
98 cout << "RT: " << (*it) << endl;
101 for (auto it = rep.begin();
102 it != rep.end(); it++)
104 cout << it->attrname() << " : " << it->getValueToString() << endl;
107 vector<OCRepresentation> children = rep.getChildren();
109 for (auto it = children.begin();
110 it != children.end(); it++)
116 void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep,
117 const int &eCode, const int &sequenceNumber)
121 if (eCode == OC_STACK_OK && sequenceNumber != maxSequenceNumber + 1)
123 if (sequenceNumber == OC_OBSERVE_REGISTER)
125 cout << "Observe registration action is successful" << endl;
128 cout << "OBSERVE RESULT:" << endl;
129 printRepresentation(rep);
133 if (eCode == OC_STACK_OK)
135 cout << "Observe registration failed or de-registration action failed/succeeded" << endl;
139 cout << "onObserve Response error: " << eCode << endl;
146 cout << "Exception: " << e.what() << " in onObserve" << endl;
150 void onPost(const HeaderOptions & /*headerOptions*/, const OCRepresentation &rep, const int eCode)
152 cout << "POST response: " << eCode << endl;
154 printRepresentation(rep);
157 void turnOnOffSwitch(bool toTurn)
159 OCRepresentation binarySwitch;
160 binarySwitch.setValue("value", toTurn);
162 QueryParamsMap query;
163 g_binaryswitchResource->post("oic.r.switch.binary", DEFAULT_INTERFACE, binarySwitch, query,
167 void getCollectionResource(const HeaderOptions &,
168 const OCRepresentation &rep, const int ecode)
170 cout << "Resource get: " << ecode << endl;
174 vector<OCRepresentation> children = rep.getChildren();
176 cout << "Constructing binary switch" << endl;
178 for (auto it = children.begin(); it != children.end(); it++)
180 cout << "RT: " << it->getResourceTypes().at(0) << endl;
182 if (it->getResourceTypes().at(0).compare("oic.r.switch.binary") == 0)
184 cout << "Observing " << it->getUri() << endl;
185 g_binaryswitchResource = OCPlatform::constructResourceObject(g_host,
187 static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4), true,
188 { string("oic.r.switch.binary") }, { string(DEFAULT_INTERFACE) });
190 QueryParamsMap query;
191 g_binaryswitchResource->observe(ObserveType::Observe, query, &onObserve);
196 void foundAirconditionerResource(shared_ptr<OC::OCResource> resource)
198 vector<string> rt = resource->getResourceTypes();
200 cout << "Aircondition resource found: " << resource->uri() << endl;
202 g_callbackLock.notify_all();
204 for (auto it = rt.begin(); it != rt.end(); it++)
206 cout << "RT: " << *it << endl;
208 if (it->compare("x.com.samsung.da.device") == 0)
210 cout << "Found Samsung Airconditioner" << endl;
212 QueryParamsMap query;
213 query["if"] = string(LINK_INTERFACE);
214 //Request to collection resource
215 resource->get(query, &getCollectionResource);
220 void foundDevice(shared_ptr<OC::OCResource> resource)
222 vector<string> rt = resource->getResourceTypes();
224 cout << "Device found: " << resource->uri() << endl;
225 cout << "DI: " << resource->sid() << endl;
227 g_callbackLock.notify_all();
229 for (auto it = rt.begin(); it != rt.end(); it++)
231 cout << "RT: " << *it << endl;
233 if (it->compare("oic.d.airconditioner") == 0)
235 string searchQuery = "/oic/res?di=";
236 searchQuery += resource->sid();
237 cout << "Airconditioner found" << endl;
238 OCPlatform::findResource(g_host, searchQuery,
239 static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4),
240 &foundAirconditionerResource);
242 OCPlatform::OCPresenceHandle handle;
243 if (OCPlatform::subscribeDevicePresence(handle, g_host, { resource->sid() },
244 static_cast<OCConnectivityType>
245 (CT_ADAPTER_TCP | CT_IP_USE_V4), &onObserve) != OC_STACK_OK)
247 cout << "Device presence failed" << endl;
253 void presenceDevice(OCStackResult , const unsigned int i, const string &str)
255 cout << "Presence received, i=" << i << " str=" << str << endl;
258 static FILE *client_open(const char * /*path*/, const char *mode)
260 return fopen("./aircon_controller.dat", mode);
263 int main(int argc, char *argv[])
265 if (argc != 4 && argc != 5)
267 cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and discover resources"
269 cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and discover resources" <<
274 OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink };
280 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
281 0, // Uses randomly available port
282 QualityOfService::LowQos,
286 OCPlatform::Configure(cfg);
288 OCStackResult result = OC_STACK_ERROR;
290 g_host = "coap+tcp://";
293 OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host,
298 unique_lock<mutex> lock(blocker);
302 accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
303 g_callbackLock.wait(lock);
307 accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
308 g_callbackLock.wait(lock);
309 accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
310 g_callbackLock.wait(lock);
314 cout << "Subscribing resource presence ";
316 string query = "oic.wk.d&di=F0FDE28F-36BF-49BC-89F1-6AFB8D73E93C";
318 OCPlatform::OCPresenceHandle presenceHandle;
320 result = OCPlatform::subscribePresence(presenceHandle, g_host, query,
321 static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4), &presenceDevice);
323 cout << " result: " << result << endl;
326 cout << "Finding airconditioner ";
328 result = OCPlatform::findResource(g_host, "/oic/res?rt=oic.wk.d",
329 static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4),
332 cout << " result: " << result << endl;
334 g_callbackLock.wait(lock);
336 cout << "PUT 1/0 to turn on/off air conditioner, q to terminate" << endl;
343 OCRepresentation rep;
348 turnOnOffSwitch(true);
352 turnOnOffSwitch(false);