859fe1124a4208cb4f129aecf89b97c2b18e05f0
[platform/upstream/iotivity.git] / resource / examples / presenceclient.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 // PresenceClient.cpp : A client example for presence notification
22 //
23 #include <string>
24 #include <cstdlib>
25 #include <pthread.h>
26 #include <mutex>
27 #include <condition_variable>
28 #include <getopt.h>
29 #include "OCPlatform.h"
30 #include "OCApi.h"
31
32 using namespace OC;
33
34 std::shared_ptr<OCResource> curResource;
35 std::mutex resourceLock;
36 static int TEST_CASE = 0;
37
38 static OCConnectivityType connectivityType = CT_ADAPTER_IP;
39
40 /**
41  * List of methods that can be inititated from the client
42  */
43 typedef enum {
44     TEST_UNICAST_PRESENCE_NORMAL = 1,
45     TEST_UNICAST_PRESENCE_WITH_FILTER,
46     TEST_UNICAST_PRESENCE_WITH_FILTERS,
47     TEST_MULTICAST_PRESENCE_NORMAL,
48     TEST_MULTICAST_PRESENCE_WITH_FILTER,
49     TEST_MULTICAST_PRESENCE_WITH_FILTERS,
50     MAX_TESTS
51 } CLIENT_TEST;
52
53 void printUsage()
54 {
55     std::cout << "Usage : presenceclient -t <1|2|3|4|5|6> -c <0|1>" << std::endl;
56     std::cout << "-t 1 : Discover Resources and Initiate Unicast Presence" << std::endl;
57     std::cout << "-t 2 : Discover Resources and Initiate Unicast Presence with Filter"
58               << std::endl;
59     std::cout << "-t 3 : Discover Resources and Initiate Unicast Presence with Two Filters"
60               << std::endl;
61     std::cout << "-t 4 : Discover Resources and Initiate Multicast Presence" << std::endl;
62     std::cout << "-t 5 : Discover Resources and Initiate Multicast Presence with Filter"
63               << std::endl;
64     std::cout << "-t 6 : Discover Resources and Initiate Multicast Presence with two Filters"
65             << std::endl;
66     std::cout<<"ConnectivityType: Default IP" << std::endl;
67     std::cout << "-c 0 : Send message with IP" << std::endl;
68 }
69
70 // Callback to presence
71 void presenceHandler(OCStackResult result, const unsigned int nonce, const std::string& hostAddress)
72 {
73     std::cout << "Received presence notification from : " << hostAddress << std::endl;
74     std::cout << "In presenceHandler: ";
75
76     switch(result)
77     {
78         case OC_STACK_OK:
79             std::cout << "Nonce# " << nonce << std::endl;
80             break;
81         case OC_STACK_PRESENCE_STOPPED:
82             std::cout << "Presence Stopped\n";
83             break;
84         case OC_STACK_PRESENCE_TIMEOUT:
85             std::cout << "Presence Timeout\n";
86             break;
87         default:
88             std::cout << "Error\n";
89             break;
90     }
91 }
92
93 // Callback to found resources
94 void foundResource(std::shared_ptr<OCResource> resource)
95 {
96     std::lock_guard<std::mutex> lock(resourceLock);
97     if(curResource)
98     {
99         std::cout << "Found another resource, ignoring"<<std::endl;
100         return;
101     }
102
103     std::string resourceURI;
104     std::string hostAddress;
105     std::string platformDiscoveryURI = "/oic/p";
106     std::string deviceDiscoveryURI   = "/oic/d";
107
108     try
109     {
110         // Do some operations with resource object.
111         if(resource)
112         {
113             std::cout<<"DISCOVERED Resource:"<<std::endl;
114             // Get the resource URI
115             resourceURI = resource->uri();
116             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
117
118             // Get the resource host address
119             hostAddress = resource->host();
120             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
121
122             // Get the resource types
123             std::cout << "\tList of resource types: " << std::endl;
124             for(auto &resourceTypes : resource->getResourceTypes())
125             {
126                 std::cout << "\t\t" << resourceTypes << std::endl;
127             }
128
129             // Get the resource interfaces
130             std::cout << "\tList of resource interfaces: " << std::endl;
131             for(auto &resourceInterfaces : resource->getResourceInterfaces())
132             {
133                 std::cout << "\t\t" << resourceInterfaces << std::endl;
134             }
135
136             OCStackResult ret;
137
138              std::cout << "Querying for platform information... " << std::endl;
139
140              ret = OCPlatform::getPlatformInfo("", platformDiscoveryURI, CT_ADAPTER_IP, NULL);
141
142              if (ret == OC_STACK_OK)
143              {
144                  std::cout << "Get platform information is done." << std::endl;
145              }
146              else
147              {
148                  std::cout << "Get platform information failed." << std::endl;
149              }
150
151              std::cout << "Querying for device information... " << std::endl;
152
153              ret = OCPlatform::getDeviceInfo(resource->host(), deviceDiscoveryURI, CT_ADAPTER_IP,
154                      NULL);
155
156              if (ret == OC_STACK_OK)
157              {
158                  std::cout << "Getting device information is done." << std::endl;
159              }
160              else
161              {
162                  std::cout << "Getting device information failed." << std::endl;
163              }
164
165             if(resourceURI == "/a/light")
166             {
167                 OCStackResult result = OC_STACK_OK;
168                 curResource = resource;
169                 OCPlatform::OCPresenceHandle presenceHandle = nullptr;
170
171                 if(TEST_CASE == TEST_UNICAST_PRESENCE_NORMAL)
172                 {
173                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
174                             connectivityType, &presenceHandler);
175                     if(result == OC_STACK_OK)
176                     {
177                         std::cout<< "Subscribed to unicast address: " << hostAddress << std::endl;
178                     }
179                     else
180                     {
181                         std::cout<< "Failed to subscribe to unicast address:" << hostAddress
182                                 << std::endl;
183                     }
184                 }
185                 if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTER ||
186                         TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
187                 {
188                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
189                             "core.light", connectivityType, &presenceHandler);
190                     if(result == OC_STACK_OK)
191                     {
192                         std::cout<< "Subscribed to unicast address: " << hostAddress;
193                     }
194                     else
195                     {
196                         std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
197                     }
198                     std::cout << " with resource type \"core.light\"." << std::endl;
199                 }
200                 if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
201                 {
202                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress, "core.fan",
203                             connectivityType, &presenceHandler);
204                     if(result == OC_STACK_OK)
205                     {
206                         std::cout<< "Subscribed to unicast address: " << hostAddress;
207                     }
208                     else
209                     {
210                         std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
211                     }
212                     std::cout << " with resource type \"core.fan\"." << std::endl;
213                 }
214             }
215         }
216         else
217         {
218             // Resource is invalid
219             std::cout << "Resource is invalid" << std::endl;
220         }
221
222     }
223     catch(std::exception& e)
224     {
225         std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
226         //log(e.what());
227     }
228 }
229
230 int main(int argc, char* argv[]) {
231
232     std::ostringstream requestURI;
233
234     int opt;
235
236     int optionSelected;
237
238     try
239     {
240         while ((opt = getopt(argc, argv, "t:c:")) != -1)
241         {
242             switch(opt)
243             {
244                 case 't':
245                     TEST_CASE = std::stoi(optarg);
246                     break;
247                 case 'c':
248                     std::size_t inputValLen;
249                     optionSelected = std::stoi(optarg, &inputValLen);
250
251                     if(inputValLen == strlen(optarg))
252                     {
253                         if(optionSelected == 0)
254                         {
255                             std::cout << "Using IP."<< std::endl;
256                             connectivityType = CT_ADAPTER_IP;
257                         }
258                         else
259                         {
260                             std::cout << "Invalid connectivity type selected. Using default IP"
261                                 << std::endl;
262                         }
263                     }
264                     else
265                     {
266                         std::cout << "Invalid connectivity type selected. Using default IP"
267                             << std::endl;
268                     }
269                     break;
270                 default:
271                     printUsage();
272                     return -1;
273             }
274         }
275     }
276     catch(std::exception& )
277     {
278         std::cout << "Invalid input argument. Using IP as connectivity type"
279             << std::endl;
280     }
281
282     if(TEST_CASE >= MAX_TESTS || TEST_CASE <= 0)
283     {
284         printUsage();
285         return -1;
286     }
287
288     // Create PlatformConfig object
289     PlatformConfig cfg {
290         OC::ServiceType::InProc,
291         OC::ModeType::Client,
292         "0.0.0.0",
293         0,
294         OC::QualityOfService::LowQos
295     };
296
297     OCPlatform::Configure(cfg);
298
299     try
300     {
301         std::cout << "Created Platform..."<<std::endl;
302
303         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
304         OCStackResult result = OC_STACK_OK;
305
306         if(TEST_CASE == TEST_MULTICAST_PRESENCE_NORMAL)
307         {
308             result = OCPlatform::subscribePresence(presenceHandle,
309                                                    "",
310                                                    connectivityType,
311                                                    presenceHandler);
312
313             if(result == OC_STACK_OK)
314             {
315                 std::cout << "Subscribed to multicast presence." << std::endl;
316             }
317             else
318             {
319                 std::cout << "Failed to subscribe to multicast presence." << std::endl;
320             }
321         }
322         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTER)
323         {
324             result = OCPlatform::subscribePresence(presenceHandle,
325                                                    "", "core.light",
326                                                    connectivityType,
327                                                    &presenceHandler);
328             if(result == OC_STACK_OK)
329             {
330                 std::cout << "Subscribed to multicast presence with resource type";
331             }
332             else
333             {
334                 std::cout << "Failed to subscribe to multicast presence with resource type";
335             }
336             std::cout << "\"core.light\"." << std::endl;
337         }
338         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTERS)
339         {
340             result = OCPlatform::subscribePresence(presenceHandle,
341                                                    "", "core.light",
342                                                    connectivityType,
343                                                    &presenceHandler);
344             if(result == OC_STACK_OK)
345             {
346                 std::cout << "Subscribed to multicast presence with resource type";
347             }
348             else
349             {
350                 std::cout << "Failed to subscribe to multicast presence with resource type";
351             }
352             std::cout << "\"core.light\"." << std::endl;
353
354             result = OCPlatform::subscribePresence(presenceHandle,
355                                                    "", "core.fan",
356                                                    connectivityType,
357                                                    &presenceHandler);
358             if(result == OC_STACK_OK)
359             {
360                 std::cout<< "Subscribed to multicast presence with resource type";
361             }
362             else
363             {
364                 std::cout << "Failed to subscribe to multicast presence with resource type.";
365             }
366             std::cout << "\"core.fan\"." << std::endl;
367         }
368         else
369         {
370             // Find all resources
371             requestURI << OC_RSRVD_WELL_KNOWN_URI;
372
373             result = OCPlatform::findResource("", requestURI.str(),
374                     CT_DEFAULT, &foundResource);
375             if(result == OC_STACK_OK)
376             {
377                 std::cout << "Finding Resource... " << std::endl;
378             }
379             else
380             {
381                 std::cout << "Failed to request to find resource(s)." << std::endl;
382             }
383         }
384         //
385         // A condition variable will free the mutex it is given, then do a non-
386         // intensive block until 'notify' is called on it.  In this case, since we
387         // don't ever call cv.notify, this should be a non-processor intensive version
388         // of while(true);
389         std::mutex blocker;
390         std::condition_variable cv;
391         std::unique_lock<std::mutex> lock(blocker);
392         cv.wait(lock);
393
394     }
395     catch(OCException& e)
396     {
397         oclog() << "Exception in main: "<< e.what();
398     }
399
400     return 0;
401 }
402
403