Imported Upstream version 0.9.2
[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
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     try
106     {
107         // Do some operations with resource object.
108         if(resource)
109         {
110             std::cout<<"DISCOVERED Resource:"<<std::endl;
111             // Get the resource URI
112             resourceURI = resource->uri();
113             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
114
115             // Get the resource host address
116             hostAddress = resource->host();
117             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
118
119             // Get the resource types
120             std::cout << "\tList of resource types: " << std::endl;
121             for(auto &resourceTypes : resource->getResourceTypes())
122             {
123                 std::cout << "\t\t" << resourceTypes << std::endl;
124             }
125
126             // Get the resource interfaces
127             std::cout << "\tList of resource interfaces: " << std::endl;
128             for(auto &resourceInterfaces : resource->getResourceInterfaces())
129             {
130                 std::cout << "\t\t" << resourceInterfaces << std::endl;
131             }
132
133             if(resourceURI == "/a/light")
134             {
135                 OCStackResult result = OC_STACK_OK;
136                 curResource = resource;
137                 OCPlatform::OCPresenceHandle presenceHandle = nullptr;
138
139                 if(TEST_CASE == TEST_UNICAST_PRESENCE_NORMAL)
140                 {
141                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
142                             connectivityType, &presenceHandler);
143                     if(result == OC_STACK_OK)
144                     {
145                         std::cout<< "Subscribed to unicast address: " << hostAddress << std::endl;
146                     }
147                     else
148                     {
149                         std::cout<< "Failed to subscribe to unicast address:" << hostAddress
150                                 << std::endl;
151                     }
152                 }
153                 if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTER ||
154                         TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
155                 {
156                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
157                             "core.light", connectivityType, &presenceHandler);
158                     if(result == OC_STACK_OK)
159                     {
160                         std::cout<< "Subscribed to unicast address: " << hostAddress;
161                     }
162                     else
163                     {
164                         std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
165                     }
166                     std::cout << " with resource type \"core.light\"." << std::endl;
167                 }
168                 if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
169                 {
170                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress, "core.fan",
171                             connectivityType, &presenceHandler);
172                     if(result == OC_STACK_OK)
173                     {
174                         std::cout<< "Subscribed to unicast address: " << hostAddress;
175                     }
176                     else
177                     {
178                         std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
179                     }
180                     std::cout << " with resource type \"core.fan\"." << std::endl;
181                 }
182             }
183         }
184         else
185         {
186             // Resource is invalid
187             std::cout << "Resource is invalid" << std::endl;
188         }
189
190     }
191     catch(std::exception& e)
192     {
193         std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
194         //log(e.what());
195     }
196 }
197
198 int main(int argc, char* argv[]) {
199
200     std::ostringstream requestURI;
201
202     int opt;
203
204     int optionSelected;
205
206     try
207     {
208         while ((opt = getopt(argc, argv, "t:c:")) != -1)
209         {
210             switch(opt)
211             {
212                 case 't':
213                     TEST_CASE = std::stoi(optarg);
214                     break;
215                 case 'c':
216                     std::size_t inputValLen;
217                     optionSelected = std::stoi(optarg, &inputValLen);
218
219                     if(inputValLen == strlen(optarg))
220                     {
221                         if(optionSelected == 0)
222                         {
223                             std::cout << "Using IP."<< std::endl;
224                             connectivityType = CT_ADAPTER_IP;
225                         }
226                         else
227                         {
228                             std::cout << "Invalid connectivity type selected. Using default IP"
229                                 << std::endl;
230                         }
231                     }
232                     else
233                     {
234                         std::cout << "Invalid connectivity type selected. Using default IP"
235                             << std::endl;
236                     }
237                     break;
238                 default:
239                     printUsage();
240                     return -1;
241             }
242         }
243     }
244     catch(std::exception& )
245     {
246         std::cout << "Invalid input argument. Using IP as connectivity type"
247             << std::endl;
248     }
249
250     if(TEST_CASE >= MAX_TESTS || TEST_CASE <= 0)
251     {
252         printUsage();
253         return -1;
254     }
255
256     // Create PlatformConfig object
257     PlatformConfig cfg {
258         OC::ServiceType::InProc,
259         OC::ModeType::Client,
260         "0.0.0.0",
261         0,
262         OC::QualityOfService::LowQos
263     };
264
265     OCPlatform::Configure(cfg);
266
267     try
268     {
269         std::cout << "Created Platform..."<<std::endl;
270
271         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
272         OCStackResult result = OC_STACK_OK;
273
274         std::ostringstream multicastPresenceURI;
275         multicastPresenceURI << "coap://" << OC_MULTICAST_PREFIX;
276
277         if(TEST_CASE == TEST_MULTICAST_PRESENCE_NORMAL)
278         {
279             result = OCPlatform::subscribePresence(presenceHandle,
280                     multicastPresenceURI.str(), connectivityType, presenceHandler);
281
282             if(result == OC_STACK_OK)
283             {
284                 std::cout << "Subscribed to multicast presence." << std::endl;
285             }
286             else
287             {
288                 std::cout << "Failed to subscribe to multicast presence." << std::endl;
289             }
290         }
291         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTER)
292         {
293             result = OCPlatform::subscribePresence(presenceHandle, multicastPresenceURI.str(), "core.light",
294                     connectivityType, &presenceHandler);
295             if(result == OC_STACK_OK)
296             {
297                 std::cout << "Subscribed to multicast presence with resource type";
298             }
299             else
300             {
301                 std::cout << "Failed to subscribe to multicast presence with resource type";
302             }
303             std::cout << "\"core.light\"." << std::endl;
304         }
305         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTERS)
306         {
307             result = OCPlatform::subscribePresence(presenceHandle, multicastPresenceURI.str(), "core.light",
308                     connectivityType, &presenceHandler);
309             if(result == OC_STACK_OK)
310             {
311                 std::cout << "Subscribed to multicast presence with resource type";
312             }
313             else
314             {
315                 std::cout << "Failed to subscribe to multicast presence with resource type";
316             }
317             std::cout << "\"core.light\"." << std::endl;
318
319             result = OCPlatform::subscribePresence(presenceHandle, multicastPresenceURI.str(), "core.fan",
320                     connectivityType, &presenceHandler);
321             if(result == OC_STACK_OK)
322             {
323                 std::cout<< "Subscribed to multicast presence with resource type";
324             }
325             else
326             {
327                 std::cout << "Failed to subscribe to multicast presence with resource type.";
328             }
329             std::cout << "\"core.fan\"." << std::endl;
330         }
331         else
332         {
333             // Find all resources
334             requestURI << OC_RSRVD_WELL_KNOWN_URI;
335
336             result = OCPlatform::findResource("", requestURI.str(),
337                     CT_DEFAULT, &foundResource);
338             if(result == OC_STACK_OK)
339             {
340                 std::cout << "Finding Resource... " << std::endl;
341             }
342             else
343             {
344                 std::cout << "Failed to request to find resource(s)." << std::endl;
345             }
346         }
347         //
348         // A condition variable will free the mutex it is given, then do a non-
349         // intensive block until 'notify' is called on it.  In this case, since we
350         // don't ever call cv.notify, this should be a non-processor intensive version
351         // of while(true);
352         std::mutex blocker;
353         std::condition_variable cv;
354         std::unique_lock<std::mutex> lock(blocker);
355         cv.wait(lock);
356
357     }
358     catch(OCException& e)
359     {
360         oclog() << "Exception in main: "<< e.what();
361     }
362
363     return 0;
364 }
365
366