replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / examples / presenceclient.cpp
index 6fd7df3..72b672a 100644 (file)
 #include <string>
 #include <cstdlib>
 #include <pthread.h>
+#include <mutex>
+#include <condition_variable>
+#include <getopt.h>
 #include "OCPlatform.h"
 #include "OCApi.h"
 
 using namespace OC;
 
 std::shared_ptr<OCResource> curResource;
-
+std::mutex resourceLock;
 static int TEST_CASE = 0;
 
+static OCConnectivityType connectivityType = CT_ADAPTER_IP;
+
 /**
  * List of methods that can be inititated from the client
  */
 typedef enum {
     TEST_UNICAST_PRESENCE_NORMAL = 1,
     TEST_UNICAST_PRESENCE_WITH_FILTER,
+    TEST_UNICAST_PRESENCE_WITH_FILTERS,
     TEST_MULTICAST_PRESENCE_NORMAL,
     TEST_MULTICAST_PRESENCE_WITH_FILTER,
+    TEST_MULTICAST_PRESENCE_WITH_FILTERS,
     MAX_TESTS
 } CLIENT_TEST;
 
 void printUsage()
 {
-    std::cout << "Usage : presenceclient -t <1|2>" << std::endl;
+    std::cout << "Usage : presenceclient -t <1|2|3|4|5|6> -c <0|1>" << std::endl;
     std::cout << "-t 1 : Discover Resources and Initiate Unicast Presence" << std::endl;
     std::cout << "-t 2 : Discover Resources and Initiate Unicast Presence with Filter"
               << std::endl;
-    std::cout << "-t 3 : Discover Resources and Initiate Multicast Presence" << std::endl;
-    std::cout << "-t 4 : Discover Resources and Initiate Multicast Presence with Filter"
+    std::cout << "-t 3 : Discover Resources and Initiate Unicast Presence with Two Filters"
+              << std::endl;
+    std::cout << "-t 4 : Discover Resources and Initiate Multicast Presence" << std::endl;
+    std::cout << "-t 5 : Discover Resources and Initiate Multicast Presence with Filter"
               << std::endl;
+    std::cout << "-t 6 : Discover Resources and Initiate Multicast Presence with two Filters"
+            << std::endl;
+    std::cout<<"ConnectivityType: Default IP" << std::endl;
+    std::cout << "-c 0 : Send message with IP" << std::endl;
 }
 
 // Callback to presence
-void presenceHandler(OCStackResult result, const unsigned int nonce)
+void presenceHandler(OCStackResult result, const unsigned int nonce, const std::string& hostAddress)
 {
+    std::cout << "Received presence notification from : " << hostAddress << std::endl;
     std::cout << "In presenceHandler: ";
 
     switch(result)
@@ -70,9 +84,6 @@ void presenceHandler(OCStackResult result, const unsigned int nonce)
         case OC_STACK_PRESENCE_TIMEOUT:
             std::cout << "Presence Timeout\n";
             break;
-        case OC_STACK_VIRTUAL_DO_NOT_HANDLE:
-            std::cout << "Virtual do not handle\n";
-            break;
         default:
             std::cout << "Error\n";
             break;
@@ -82,9 +93,11 @@ void presenceHandler(OCStackResult result, const unsigned int nonce)
 // Callback to found resources
 void foundResource(std::shared_ptr<OCResource> resource)
 {
+    std::lock_guard<std::mutex> lock(resourceLock);
     if(curResource)
     {
         std::cout << "Found another resource, ignoring"<<std::endl;
+        return;
     }
 
     std::string resourceURI;
@@ -119,21 +132,52 @@ void foundResource(std::shared_ptr<OCResource> resource)
 
             if(resourceURI == "/a/light")
             {
+                OCStackResult result = OC_STACK_OK;
                 curResource = resource;
-                OCPlatform::OCPresenceHandle presenceHandle;
+                OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
                 if(TEST_CASE == TEST_UNICAST_PRESENCE_NORMAL)
                 {
-                    OCPlatform::subscribePresence(presenceHandle, hostAddress,
-                            &presenceHandler);
-                    std::cout<< "Subscribed to unicast address:" << hostAddress <<std::endl;
+                    result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
+                            connectivityType, &presenceHandler);
+                    if(result == OC_STACK_OK)
+                    {
+                        std::cout<< "Subscribed to unicast address: " << hostAddress << std::endl;
+                    }
+                    else
+                    {
+                        std::cout<< "Failed to subscribe to unicast address:" << hostAddress
+                                << std::endl;
+                    }
+                }
+                if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTER ||
+                        TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
+                {
+                    result = OCPlatform::subscribePresence(presenceHandle, hostAddress,
+                            "core.light", connectivityType, &presenceHandler);
+                    if(result == OC_STACK_OK)
+                    {
+                        std::cout<< "Subscribed to unicast address: " << hostAddress;
+                    }
+                    else
+                    {
+                        std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
+                    }
+                    std::cout << " with resource type \"core.light\"." << std::endl;
                 }
-                else if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTER)
+                if(TEST_CASE == TEST_UNICAST_PRESENCE_WITH_FILTERS)
                 {
-                    OCPlatform::subscribePresence(presenceHandle, hostAddress, "core.light",
-                            &presenceHandler);
-                    std::cout<< "Subscribed (with resource type) to unicast address:"
-                                << hostAddress << std::endl;
+                    result = OCPlatform::subscribePresence(presenceHandle, hostAddress, "core.fan",
+                            connectivityType, &presenceHandler);
+                    if(result == OC_STACK_OK)
+                    {
+                        std::cout<< "Subscribed to unicast address: " << hostAddress;
+                    }
+                    else
+                    {
+                        std::cout<< "Failed to subscribe to unicast address: " << hostAddress;
+                    }
+                    std::cout << " with resource type \"core.fan\"." << std::endl;
                 }
             }
         }
@@ -146,25 +190,63 @@ void foundResource(std::shared_ptr<OCResource> resource)
     }
     catch(std::exception& e)
     {
+        std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
         //log(e.what());
     }
 }
 
 int main(int argc, char* argv[]) {
+
+    std::ostringstream requestURI;
+
     int opt;
 
-    while ((opt = getopt(argc, argv, "t:")) != -1)
+    int optionSelected;
+
+    try
     {
-        switch(opt)
+        while ((opt = getopt(argc, argv, "t:c:")) != -1)
         {
-            case 't':
-                TEST_CASE = atoi(optarg);
-                break;
-            default:
-                printUsage();
-                return -1;
+            switch(opt)
+            {
+                case 't':
+                    TEST_CASE = std::stoi(optarg);
+                    break;
+                case 'c':
+                    std::size_t inputValLen;
+                    optionSelected = std::stoi(optarg, &inputValLen);
+
+                    if(inputValLen == strlen(optarg))
+                    {
+                        if(optionSelected == 0)
+                        {
+                            std::cout << "Using IP."<< std::endl;
+                            connectivityType = CT_ADAPTER_IP;
+                        }
+                        else
+                        {
+                            std::cout << "Invalid connectivity type selected. Using default IP"
+                                << std::endl;
+                        }
+                    }
+                    else
+                    {
+                        std::cout << "Invalid connectivity type selected. Using default IP"
+                            << std::endl;
+                    }
+                    break;
+                default:
+                    printUsage();
+                    return -1;
+            }
         }
     }
+    catch(std::exception& )
+    {
+        std::cout << "Invalid input argument. Using IP as connectivity type"
+            << std::endl;
+    }
+
     if(TEST_CASE >= MAX_TESTS || TEST_CASE <= 0)
     {
         printUsage();
@@ -186,35 +268,104 @@ int main(int argc, char* argv[]) {
     {
         std::cout << "Created Platform..."<<std::endl;
 
-        OCPlatform::OCPresenceHandle presenceHandle;
+        OCPlatform::OCPresenceHandle presenceHandle = nullptr;
+        OCStackResult result = OC_STACK_OK;
 
         if(TEST_CASE == TEST_MULTICAST_PRESENCE_NORMAL)
         {
-            OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, presenceHandler);
-            std::cout<< "Subscribed to multicast" <<std::endl;
+            result = OCPlatform::subscribePresence(presenceHandle,
+                                                   "",
+                                                   connectivityType,
+                                                   presenceHandler);
+
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Subscribed to multicast presence." << std::endl;
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence." << std::endl;
+            }
         }
         else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTER)
         {
-            OCPlatform::subscribePresence(presenceHandle, OC_MULTICAST_IP, "core.light",
-                    &presenceHandler);
-            std::cout<< "Subscribed to multicast with resource type" <<std::endl;
+            result = OCPlatform::subscribePresence(presenceHandle,
+                                                   "", "core.light",
+                                                   connectivityType,
+                                                   &presenceHandler);
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Subscribed to multicast presence with resource type";
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence with resource type";
+            }
+            std::cout << "\"core.light\"." << std::endl;
+        }
+        else if(TEST_CASE == TEST_MULTICAST_PRESENCE_WITH_FILTERS)
+        {
+            result = OCPlatform::subscribePresence(presenceHandle,
+                                                   "", "core.light",
+                                                   connectivityType,
+                                                   &presenceHandler);
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Subscribed to multicast presence with resource type";
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence with resource type";
+            }
+            std::cout << "\"core.light\"." << std::endl;
+
+            result = OCPlatform::subscribePresence(presenceHandle,
+                                                   "", "core.fan",
+                                                   connectivityType,
+                                                   &presenceHandler);
+            if(result == OC_STACK_OK)
+            {
+                std::cout<< "Subscribed to multicast presence with resource type";
+            }
+            else
+            {
+                std::cout << "Failed to subscribe to multicast presence with resource type.";
+            }
+            std::cout << "\"core.fan\"." << std::endl;
         }
         else
         {
             // Find all resources
-            OCPlatform::findResource("", "coap://224.0.1.187/oc/core", &foundResource);
-            std::cout<< "Finding Resource... " <<std::endl;
-        }
-        while(true)
-        {
-            // some operations
+            requestURI << OC_RSRVD_WELL_KNOWN_URI;
+
+            result = OCPlatform::findResource("", requestURI.str(),
+                    CT_DEFAULT, &foundResource);
+            if(result == OC_STACK_OK)
+            {
+                std::cout << "Finding Resource... " << std::endl;
+            }
+            else
+            {
+                std::cout << "Failed to request to find resource(s)." << std::endl;
+            }
         }
+        //
+        // A condition variable will free the mutex it is given, then do a non-
+        // intensive block until 'notify' is called on it.  In this case, since we
+        // don't ever call cv.notify, this should be a non-processor intensive version
+        // of while(true);
+        std::mutex blocker;
+        std::condition_variable cv;
+        std::unique_lock<std::mutex> lock(blocker);
+        cv.wait(lock);
 
-    }catch(OCException& e)
+    }
+    catch(OCException& e)
     {
-        //log(e.what());
+        oclog() << "Exception in main: "<< e.what();
     }
 
     return 0;
 }
 
+