6dc5e0264623136ab5f926e169f6d5d9ff1c15a4
[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 <pthread.h>
9 #include <unistd.h>
10
11 #include "ocstack.h"
12 #include "ocpayload.h"
13
14 #include <OCApi.h>
15 #include <OCPlatform.h>
16
17 #define DEFAULT_CONTEXT_VALUE 0x99
18
19 #define maxSequenceNumber 0xFFFFFF
20
21 using namespace OC;
22 using namespace std;
23
24
25 condition_variable  g_callbackLock;
26 std::string         g_uid;
27 std::string         g_accesstoken;
28
29 string              g_host;
30 OC::OCResource::Ptr g_binaryswitchResource;
31
32 void printRepresentation(OCRepPayloadValue *value)
33 {
34     while (value)
35     {
36         std::cout << "Key: " << value->name;
37         switch (value->type)
38         {
39             case OCREP_PROP_NULL:
40                 std::cout << " Value: None" << std::endl;
41                 break;
42             case OCREP_PROP_INT:
43                 std::cout << " Value: " << value->i << std::endl;
44                 break;
45             case OCREP_PROP_DOUBLE:
46                 std::cout << " Value: " << value->d << std::endl;
47                 break;
48             case OCREP_PROP_BOOL:
49                 std::cout << " Value: " << value->b << std::endl;
50                 break;
51             case OCREP_PROP_STRING:
52                 std::cout << " Value: " << value->str << std::endl;
53                 break;
54             case OCREP_PROP_BYTE_STRING:
55                 std::cout << " Value: Byte String" << std::endl;
56                 break;
57             case OCREP_PROP_OBJECT:
58                 std::cout << " Value: Object" << std::endl;
59                 break;
60             case OCREP_PROP_ARRAY:
61                 std::cout << " Value: Array" << std::endl;
62                 break;
63         }
64
65         if (strcmp(value->name, "accesstoken") == 0)
66         {
67             g_accesstoken = value->str;
68         }
69
70         if (strcmp(value->name, "uid") == 0)
71         {
72             g_uid = value->str;
73         }
74
75         value = value->next;
76     }
77 }
78
79 void handleLoginoutCB(const HeaderOptions &,
80                       const OCRepresentation &rep, const int ecode)
81 {
82     cout << "Login/out response received code: " << ecode << endl;
83
84     if (rep.getPayload() != NULL)
85     {
86         printRepresentation(rep.getPayload()->values);
87     }
88
89     g_callbackLock.notify_all();
90 }
91
92 void printRepresentation(const OCRepresentation &rep)
93 {
94     cout << "URI: " << rep.getUri() << endl;
95
96     vector<string> rt = rep.getResourceTypes();
97     for (auto it = rt.begin(); it != rt.end(); it++)
98     {
99         cout << "RT: " << (*it) << endl;
100     }
101
102     for (auto it = rep.begin();
103          it != rep.end(); it++)
104     {
105         cout << it->attrname() << " : " << it->getValueToString() << endl;
106     }
107
108     vector<OCRepresentation> children = rep.getChildren();
109
110     for (auto it = children.begin();
111          it != children.end(); it++)
112     {
113         printRepresentation(*it);
114     }
115 }
116
117 void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation &rep,
118                const int &eCode, const int &sequenceNumber)
119 {
120     try
121     {
122         if (eCode == OC_STACK_OK && sequenceNumber != maxSequenceNumber + 1)
123         {
124             if (sequenceNumber == OC_OBSERVE_REGISTER)
125             {
126                 cout << "Observe registration action is successful" << endl;
127             }
128
129             cout << "OBSERVE RESULT:" << endl;
130             printRepresentation(rep);
131         }
132         else
133         {
134             if (eCode == OC_STACK_OK)
135             {
136                 std::cout << "Observe registration failed or de-registration action failed/succeeded" << std::endl;
137             }
138             else
139             {
140                 cout << "onObserve Response error: " << eCode << endl;
141                 exit(-1);
142             }
143         }
144     }
145     catch (exception &e)
146     {
147         cout << "Exception: " << e.what() << " in onObserve" << endl;
148     }
149 }
150
151 void onPut(const HeaderOptions & /*headerOptions*/, const OCRepresentation &rep, const int eCode)
152 {
153     cout << "PUT response: " << eCode << endl;
154
155     printRepresentation(rep);
156 }
157
158 void turnOnOffSwitch(bool toTurn)
159 {
160     OCRepresentation binarySwitch;
161     binarySwitch.setValue("value", toTurn);
162
163     QueryParamsMap      query;
164     g_binaryswitchResource->post("oic.r.switch.binary", DEFAULT_INTERFACE, binarySwitch, query, &onPut);
165 }
166
167 void getCollectionResource(const HeaderOptions &,
168                            const OCRepresentation &rep, const int ecode)
169 {
170     cout << "Resource get: " << ecode << endl;
171
172     printRepresentation(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     }
243 }
244
245 void presenceDevice(OCStackResult , const unsigned int i, const std::string &str)
246 {
247     cout << "Presence received, i=" << i << " str=" << str << endl;
248 }
249
250 static FILE *client_open(const char * /*path*/, const char *mode)
251 {
252     return fopen("./resource_controller.dat", mode);
253 }
254
255 int main(int argc, char *argv[])
256 {
257     if (argc != 4 && argc != 5)
258     {
259         cout << "Put \"[host-ipaddress:port] [authprovider] [authcode]\" for sign-up and sign-in and discover resources"
260              << endl;
261         cout << "Put \"[host-ipaddress:port] [uid] [accessToken] 1\" for sign-in and discover resources" <<
262              endl;
263         return 0;
264     }
265
266     OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink };
267
268     PlatformConfig cfg
269     {
270         ServiceType::InProc,
271         ModeType::Both,
272         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
273         0,         // Uses randomly available port
274         QualityOfService::LowQos,
275         &ps
276     };
277
278     OCPlatform::Configure(cfg);
279
280     OCStackResult result = OC_STACK_ERROR;
281
282     g_host = "coap+tcp://";
283     g_host += argv[1];
284
285     OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host,
286                                        CT_ADAPTER_TCP);
287
288
289     mutex blocker;
290     unique_lock<std::mutex> lock(blocker);
291
292     if (argc == 5)
293     {
294         accountMgr->signIn(argv[2], argv[3], &handleLoginoutCB);
295         g_callbackLock.wait(lock);
296     }
297     else
298     {
299         accountMgr->signUp(argv[2], argv[3], &handleLoginoutCB);
300         g_callbackLock.wait(lock);
301         accountMgr->signIn(g_uid, g_accesstoken, &handleLoginoutCB);
302         g_callbackLock.wait(lock);
303     }
304
305     /*
306     cout << "Subscribing resource presence ";
307
308     string query = "oic.wk.d&di=F0FDE28F-36BF-49BC-89F1-6AFB8D73E93C";
309
310     OCPlatform::OCPresenceHandle presenceHandle;
311
312     result = OCPlatform::subscribePresence(presenceHandle, g_host, query,
313                                            static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4), &presenceDevice);
314
315     cout << " result: " << result << endl;
316     */
317
318     cout << "Finding airconditioner ";
319
320     result = OCPlatform::findResource(g_host, "/oic/res?rt=oic.wk.d",
321                                       static_cast<OCConnectivityType>(CT_ADAPTER_TCP | CT_IP_USE_V4),
322                                       &foundDevice);
323
324     cout << " result: " << result << endl;
325
326     g_callbackLock.wait(lock);
327
328     cout << "PUT 1/0 to turn on/off air conditioner, q to terminate" << endl;
329
330     string cmd;
331
332     while (true)
333     {
334         cin >> cmd;
335         OCRepresentation    rep;
336
337         switch (cmd[0])
338         {
339             case '1':
340                 turnOnOffSwitch(true);
341                 break;
342
343             case '0':
344                 turnOnOffSwitch(false);
345                 break;
346
347             case 'q':
348                 goto exit;
349                 break;
350         }
351     }
352
353 exit:
354     return 0;
355 }