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