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