ef5200400da06c2f4ce748293c2b61e1a4ccde21
[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
37 static int TEST_CASE = 0;
38
39 static OCConnectivityType connectivityType = OC_WIFI;
40
41 /**
42  * List of methods that can be inititated from the client
43  */
44 typedef enum {
45     TEST_UNICAST_PRESENCE_NORMAL = 1,
46     TEST_UNICAST_PRESENCE_WITH_FILTER,
47     TEST_UNICAST_PRESENCE_WITH_FILTERS,
48     TEST_MULTICAST_PRESENCE_NORMAL,
49     TEST_MULTICAST_PRESENCE_WITH_FILTER,
50     TEST_MULTICAST_PRESENCE_WITH_FILTERS,
51     MAX_TESTS
52 } CLIENT_TEST;
53
54 void printUsage()
55 {
56     std::cout << "Usage : presenceclient -t <1|2|3|4|5|6> -c <0|1>" << std::endl;
57     std::cout << "-t 1 : Discover Resources and Initiate Unicast Presence" << std::endl;
58     std::cout << "-t 2 : Discover Resources and Initiate Unicast Presence with Filter"
59               << std::endl;
60     std::cout << "-t 3 : Discover Resources and Initiate Unicast Presence with Two Filters"
61             << std::endl;
62     std::cout << "-t 4 : Discover Resources and Initiate Multicast Presence" << std::endl;
63     std::cout << "-t 5 : Discover Resources and Initiate Multicast Presence with Filter"
64               << std::endl;
65     std::cout << "-t 6 : Discover Resources and Initiate Multicast Presence with two Filters"
66                   << std::endl;
67     std::cout<<"ConnectivityType: Default WIFI" << std::endl;
68     std::cout << "-c 0 : Send message over ETHERNET interface" << std::endl;
69     std::cout << "-c 1 : Send message over WIFI interface" << std::endl;
70 }
71
72 // Callback to presence
73 void presenceHandler(OCStackResult result, const unsigned int nonce, const std::string& hostAddress)
74 {
75     std::cout << "Received presence notification from : " << hostAddress << std::endl;
76     std::cout << "In presenceHandler: ";
77
78     switch(result)
79     {
80         case OC_STACK_OK:
81             std::cout << "Nonce# " << nonce << std::endl;
82             break;
83         case OC_STACK_PRESENCE_STOPPED:
84             std::cout << "Presence Stopped\n";
85             break;
86         case OC_STACK_PRESENCE_TIMEOUT:
87             std::cout << "Presence Timeout\n";
88             break;
89         default:
90             std::cout << "Error\n";
91             break;
92     }
93 }
94
95 // Callback to found resources
96 void foundResource(std::shared_ptr<OCResource> resource)
97 {
98     std::lock_guard<std::mutex> lock(resourceLock);
99     if(curResource)
100     {
101         std::cout << "Found another resource, ignoring"<<std::endl;
102         return;
103     }
104
105     std::string resourceURI;
106     std::string hostAddress;
107     try
108     {
109         // Do some operations with resource object.
110         if(resource)
111         {
112             std::cout<<"DISCOVERED Resource:"<<std::endl;
113             // Get the resource URI
114             resourceURI = resource->uri();
115             std::cout << "\tURI of the resource: " << resourceURI << std::endl;
116
117             // Get the resource host address
118             hostAddress = resource->host();
119             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
120
121             // Get the resource types
122             std::cout << "\tList of resource types: " << std::endl;
123             for(auto &resourceTypes : resource->getResourceTypes())
124             {
125                 std::cout << "\t\t" << resourceTypes << std::endl;
126             }
127
128             // Get the resource interfaces
129             std::cout << "\tList of resource interfaces: " << std::endl;
130             for(auto &resourceInterfaces : resource->getResourceInterfaces())
131             {
132                 std::cout << "\t\t" << resourceInterfaces << std::endl;
133             }
134
135             if(resourceURI == "/a/light")
136             {
137                 OCStackResult result = OC_STACK_OK;
138                 curResource = resource;
139                 OCPlatform::OCPresenceHandle presenceHandle = nullptr;
140
141                 if(TEST_CASE == TEST_UNICAST_PRESENCE_NORMAL)
142                 {
143                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
144                             connectivityType, &presenceHandler);
145                     if(result == OC_STACK_OK)
146                     {
147                         std::cout<< "Subscribed to unicast address: " << hostAddress << std::endl;
148                     }
149                     else
150                     {
151                         std::cout<< "Failed to subscribe to unicast address:" << hostAddress
152                                 << std::endl;
153                     }
154                 }
155                 if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTER ||
156                         TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
157                 {
158                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
159                             "core.light", connectivityType, &presenceHandler);
160                     if(result == OC_STACK_OK)
161                     {
162                         std::cout<< "Subscribed to unicast address: " << hostAddress;
163                     }
164                     else
165                     {
166                         std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
167                     }
168                     std::cout << " with resource type \"core.light\"." << std::endl;
169                 }
170                 if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
171                 {
172                     result = OCPlatform::subscribePresence(presenceHandle, hostAddress, "core.fan",
173                             connectivityType, &presenceHandler);
174                     if(result == OC_STACK_OK)
175                     {
176                         std::cout<< "Subscribed to unicast address: " << hostAddress;
177                     }
178                     else
179                     {
180                         std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
181                     }
182                     std::cout << " with resource type \"core.fan\"." << std::endl;
183                 }
184             }
185         }
186         else
187         {
188             // Resource is invalid
189             std::cout << "Resource is invalid" << std::endl;
190         }
191
192     }
193     catch(std::exception& e)
194     {
195         //log(e.what());
196     }
197 }
198
199 int main(int argc, char* argv[]) {
200
201     std::ostringstream requestURI;
202
203     int opt;
204
205     int optionSelected;
206
207     try
208     {
209         while ((opt = getopt(argc, argv, "t:c:")) != -1)
210         {
211             switch(opt)
212             {
213                 case 't':
214                     TEST_CASE = std::stoi(optarg);
215                     break;
216                 case 'c':
217                     std::size_t inputValLen;
218                     optionSelected = std::stoi(optarg, &inputValLen);
219
220                     if(inputValLen == strlen(optarg))
221                     {
222                         if(optionSelected == 0)
223                         {
224                             connectivityType = OC_ETHERNET;
225                         }
226                         else if(optionSelected == 1)
227                         {
228                             connectivityType = OC_WIFI;
229                         }
230                         else
231                         {
232                             std::cout << "Invalid connectivity type selected. Using default WIFI"
233                                 << std::endl;
234                         }
235                     }
236                     else
237                     {
238                         std::cout << "Invalid connectivity type selected. Using default WIFI"
239                             << std::endl;
240                     }
241                     break;
242                 default:
243                     printUsage();
244                     return -1;
245             }
246         }
247     }
248     catch(std::exception& e)
249     {
250         std::cout << "Invalid input argument. Using WIFI as connectivity type"
251             << std::endl;
252     }
253
254     if(TEST_CASE >= MAX_TESTS || TEST_CASE <= 0)
255     {
256         printUsage();
257         return -1;
258     }
259
260     // Create PlatformConfig object
261     PlatformConfig cfg {
262         OC::ServiceType::InProc,
263         OC::ModeType::Client,
264         "0.0.0.0",
265         0,
266         OC::QualityOfService::LowQos
267     };
268
269     OCPlatform::Configure(cfg);
270
271     try
272     {
273         std::cout << "Created Platform..."<<std::endl;
274
275         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
276         OCStackResult result = OC_STACK_OK;
277
278         if(TEST_CASE == TEST_MULTICAST_PRESENCE_NORMAL)
279         {
280             result = OCPlatform::subscribePresence(presenceHandle,
281                     OC_MULTICAST_IP, connectivityType, presenceHandler);
282
283             if(result == OC_STACK_OK)
284             {
285                 std::cout << "Subscribed to multicast presence." << std::endl;
286             }
287             else
288             {
289                 std::cout << "Failed to subscribe to multicast presence." << std::endl;
290             }
291         }
292         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTER)
293         {
294             result = OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.light",
295                     connectivityType, &presenceHandler);
296             if(result == OC_STACK_OK)
297             {
298                 std::cout << "Subscribed to multicast presence with resource type";
299             }
300             else
301             {
302                 std::cout << "Failed to subscribe to multicast presence with resource type";
303             }
304             std::cout << "\"core.light\"." << std::endl;
305         }
306         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTERS)
307         {
308             result = OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.light",
309                     connectivityType, &presenceHandler);
310             if(result == OC_STACK_OK)
311             {
312                 std::cout << "Subscribed to multicast presence with resource type";
313             }
314             else
315             {
316                 std::cout << "Failed to subscribe to multicast presence with resource type";
317             }
318             std::cout << "\"core.light\"." << std::endl;
319
320             result = OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.fan",
321                     connectivityType, &presenceHandler);
322             if(result == OC_STACK_OK)
323             {
324                 std::cout<< "Subscribed to multicast presence with resource type";
325             }
326             else
327             {
328                 std::cout << "Failed to subscribe to multicast presence with resource type.";
329             }
330             std::cout << "\"core.fan\"." << std::endl;
331         }
332         else
333         {
334             // Find all resources
335             requestURI << OC_WELL_KNOWN_QUERY;
336
337             result = OCPlatform::findResource("", requestURI.str(),
338                     connectivityType, &foundResource);
339             if(result == OC_STACK_OK)
340             {
341                 std::cout << "Finding Resource... " << std::endl;
342             }
343             else
344             {
345                 std::cout << "Failed to request to find resource(s)." << std::endl;
346             }
347         }
348         //
349         // A condition variable will free the mutex it is given, then do a non-
350         // intensive block until 'notify' is called on it.  In this case, since we
351         // don't ever call cv.notify, this should be a non-processor intensive version
352         // of while(true);
353         std::mutex blocker;
354         std::condition_variable cv;
355         std::unique_lock<std::mutex> lock(blocker);
356         cv.wait(lock);
357
358     }
359     catch(OCException& e)
360     {
361         oclog() << "Exception in main: "<< e.what();
362     }
363
364     return 0;
365 }
366
367