Modify /oic/res response
[platform/upstream/iotivity.git] / cloud / samples / client / airconditioner / aircon_controller.cpp
1 #include <memory>
2 #include <iostream>
3 #include <stdexcept>
4 #include <condition_variable>
5 #include <map>
6 #include <vector>
7 #include <string>
8 #include <unistd.h>
9
10 #include "ocstack.h"
11 #include "ocpayload.h"
12
13 #include <OCApi.h>
14 #include <OCPlatform.h>
15
16 using namespace OC;
17 using namespace std;
18
19
20 condition_variable  g_callbackLock;
21 string         g_uid;
22 string         g_accesstoken;
23
24 string              g_host;
25 OC::OCResource::Ptr g_binaryswitchResource;
26
27 void printRepresentation(OCRepresentation rep)
28 {
29     for (auto itr = rep.begin(); itr != rep.end(); ++itr)
30     {
31         cout << "\t" << itr->attrname() << ":\t" << itr->getValueToString() << endl;
32         if (itr->type() == AttributeType::Vector)
33         {
34             switch (itr->base_type())
35             {
36                 case AttributeType::OCRepresentation:
37                     for (auto itr2 : (*itr).getValue<vector<OCRepresentation> >())
38                     {
39                         printRepresentation(itr2);
40                     }
41                     break;
42
43                 case AttributeType::Integer:
44                     for (auto itr2 : (*itr).getValue<vector<int> >())
45                     {
46                         cout << "\t\t" << itr2 << endl;
47                     }
48                     break;
49
50                 case AttributeType::String:
51                     for (auto itr2 : (*itr).getValue<vector<string> >())
52                     {
53                         cout << "\t\t" << itr2 << endl;
54                     }
55                     break;
56
57                 default:
58                     cout << "Unhandled base type " << itr->base_type() << endl;
59                     break;
60             }
61         }
62         else if (itr->type() == AttributeType::OCRepresentation)
63         {
64             printRepresentation((*itr).getValue<OCRepresentation>());
65         }
66     }
67 }
68
69 void handleLoginoutCB(const HeaderOptions &,
70                       const OCRepresentation &rep, const int ecode)
71 {
72     cout << "Login/out response received code: " << ecode << endl;
73
74     if (rep.getPayload() != NULL)
75     {
76         printRepresentation(rep);
77     }
78
79     if (ecode == 4)
80     {
81         g_accesstoken = rep.getValueToString("accesstoken");
82
83         g_uid = rep.getValueToString("uid");
84     }
85
86     g_callbackLock.notify_all();
87 }
88
89 void printResource(const OCRepresentation &rep)
90 {
91     cout << "URI: " << rep.getUri() << endl;
92
93     vector<string> rt = rep.getResourceTypes();
94     for (auto it = rt.begin(); it != rt.end(); it++)
95     {
96         cout << "RT: " << (*it) << endl;
97     }
98
99     for (auto it = rep.begin();
100          it != rep.end(); it++)
101     {
102         cout << it->attrname() << " : " << it->getValueToString() << endl;
103     }
104
105     vector<OCRepresentation> children = rep.getChildren();
106
107     for (auto it = children.begin();
108          it != children.end(); it++)
109     {
110         printResource(*it);
111     }
112 }
113
114 void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep,
115                const int &eCode, const int &sequenceNumber)
116 {
117     try
118     {
119         if (eCode == OC_STACK_OK && sequenceNumber <= MAX_SEQUENCE_NUMBER)
120         {
121             if (sequenceNumber == OC_OBSERVE_REGISTER)
122             {
123                 cout << "Observe registration action is successful" << endl;
124             }
125
126             cout << "OBSERVE RESULT:" << endl;
127             printRepresentation(rep);
128         }
129         else
130         {
131             if (eCode == OC_STACK_OK)
132             {
133                 cout << "Observe registration failed or de-registration action failed/succeeded" << endl;
134             }
135             else
136             {
137                 cout << "onObserve Response error: " << eCode << endl;
138                 exit(-1);
139             }
140         }
141     }
142     catch (exception &e)
143     {
144         cout << "Exception: " << e.what() << " in onObserve" << endl;
145     }
146 }
147
148 void onPost(const HeaderOptions & /*headerOptions*/, const OCRepresentation &rep, const int eCode)
149 {
150     cout << "POST response: " << eCode << endl;
151
152     printRepresentation(rep);
153 }
154
155 void turnOnOffSwitch(bool toTurn)
156 {
157     OCRepresentation binarySwitch;
158     binarySwitch.setValue("value", toTurn);
159
160     QueryParamsMap      query;
161     g_binaryswitchResource->post("oic.r.switch.binary", DEFAULT_INTERFACE, binarySwitch, query,
162                                  &onPost);
163 }
164
165 void getCollectionResource(const HeaderOptions &,
166                            const OCRepresentation &rep, const int ecode)
167 {
168     cout << "Resource get: " << ecode << endl;
169
170     printResource(rep);
171
172     vector<OCRepresentation> children = rep.getChildren();
173
174     cout << "Constructing binary switch" << endl;
175
176     for (auto it = children.begin(); it != children.end(); it++)
177     {
178         cout << "RT: " << it->getResourceTypes().at(0) << endl;
179
180         if (it->getResourceTypes().at(0).compare("oic.r.switch.binary") == 0)
181         {
182             cout << "Observing " << it->getUri() << endl;
183             g_binaryswitchResource = OCPlatform::constructResourceObject(g_host,
184                                      it->getUri(),
185                                      static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4), true,
186             { string("oic.r.switch.binary") }, { string(DEFAULT_INTERFACE) });
187
188             QueryParamsMap      query;
189             g_binaryswitchResource->observe(ObserveType::Observe, query, &onObserve);
190         }
191     }
192 }
193
194 void foundAirconditionerResource(shared_ptr<OC::OCResource> resource)
195 {
196     vector<string> rt = resource->getResourceTypes();
197
198     cout << "Aircondition resource found: " << resource->uri() << endl;
199
200     g_callbackLock.notify_all();
201
202     for (auto it = rt.begin(); it != rt.end(); it++)
203     {
204         cout << "RT: " << *it << endl;
205
206         if (it->compare("x.com.samsung.da.device") == 0)
207         {
208             cout << "Found Samsung Airconditioner" << endl;
209
210             QueryParamsMap      query;
211             query["if"] = string(LINK_INTERFACE);
212             //Request to collection resource
213             resource->get(query, &getCollectionResource);
214         }
215     }
216 }
217
218 void foundDevice(shared_ptr<OC::OCResource> resource)
219 {
220     cout << "Found device called!" << endl;
221
222     vector<string> rt = resource->getResourceTypes();
223
224     cout << "Device found: " << resource->uri() << endl;
225     cout << "DI: " << resource->sid() << endl;
226
227     g_callbackLock.notify_all();
228
229     for (auto it = rt.begin(); it != rt.end(); it++)
230     {
231         cout << "RT: " << *it << endl;
232
233         if (it->compare("oic.d.airconditioner") == 0)
234         {
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);
241
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)
246             {
247                 cout << "Device presence failed" << endl;
248             }
249         }
250     }
251 }
252
253 void errorFoundDevice(const std::string &uri, const int ecode)
254 {
255     cout << "Found device error on " << uri << " code " << ecode << endl;
256     g_callbackLock.notify_all();
257 }
258
259 void presenceDevice(OCStackResult , const unsigned int i, const string &str)
260 {
261     cout << "Presence received, i=" << i << " str=" << str << endl;
262 }
263
264 static FILE *client_open(const char * /*path*/, const char *mode)
265 {
266     return fopen("./aircon_controller.dat", mode);
267 }
268
269 int main(int argc, char *argv[])
270 {
271     if (argc != 4 && argc != 5)
272     {
273         cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and discover resources"
274              << endl;
275         cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and discover resources" <<
276              endl;
277         return 0;
278     }
279
280     OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink };
281
282     PlatformConfig cfg
283     {
284         ServiceType::InProc,
285         ModeType::Both,
286         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
287         0,         // Uses randomly available port
288         QualityOfService::LowQos,
289         &ps
290     };
291
292     OCPlatform::Configure(cfg);
293
294     OCStackResult result = OC_STACK_ERROR;
295
296     g_host = "coap+tcp://";
297     g_host += argv[1];
298
299     OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host,
300                                        CT_ADAPTER_TCP);
301
302
303     mutex blocker;
304     unique_lock<mutex> lock(blocker);
305
306     if (argc == 5)
307     {
308         accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
309         g_callbackLock.wait(lock);
310     }
311     else
312     {
313         accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
314         g_callbackLock.wait(lock);
315         accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
316         g_callbackLock.wait(lock);
317     }
318
319     /*
320     cout << "Subscribing resource presence ";
321
322     string query = "oic.wk.d&di=F0FDE28F-36BF-49BC-89F1-6AFB8D73E93C";
323
324     OCPlatform::OCPresenceHandle presenceHandle;
325
326     result = OCPlatform::subscribePresence(presenceHandle, g_host, query,
327                                            static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4), &presenceDevice);
328
329     cout << " result: " << result << endl;
330     */
331
332     cout << "Finding airconditioner ";
333
334     result = OCPlatform::findResource(g_host, "/oic/res?rt=oic.wk.d",
335                                       static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4),
336                                       &foundDevice, &errorFoundDevice);
337
338     cout << " result: " << result << endl;
339
340     g_callbackLock.wait(lock);
341
342     cout << "PUT 1/0 to turn on/off air conditioner, q to terminate" << endl;
343
344     string cmd;
345
346     while (true)
347     {
348         cin >> cmd;
349         OCRepresentation    rep;
350
351         switch (cmd[0])
352         {
353             case '1':
354                 turnOnOffSwitch(true);
355                 break;
356
357             case '0':
358                 turnOnOffSwitch(false);
359                 break;
360
361             case 'q':
362                 goto exit;
363                 break;
364         }
365     }
366
367 exit:
368     return 0;
369 }