Add C++ API for Direct pairing
authorAshwini Kumar <k.ashwini@samsung.com>
Mon, 23 May 2016 08:26:22 +0000 (13:56 +0530)
committerRandeep Singh <randeep.s@samsung.com>
Tue, 14 Jun 2016 02:33:44 +0000 (02:33 +0000)
 Added C++ API for direct pairing feature
 Updated unittests for C++
 Added direct pairing sample
 Fixed Construct resource to '|' Secure flag instead of '&'

 Note: this change needs https://gerrit.iotivity.org/gerrit/#/c/8273/

Change-Id: I4a1cfc27206adf7308388406d0c8821aa46d87a8
Signed-off-by: Ashwini Kumar <k.ashwini@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/8277
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
23 files changed:
resource/csdk/security/src/directpairing.c
resource/examples/SConscript
resource/examples/directpairingclient.cpp [new file with mode: 0644]
resource/examples/oic_svr_db_client_directpairing.dat [new file with mode: 0644]
resource/examples/oic_svr_db_client_directpairing.json [new file with mode: 0644]
resource/include/IClientWrapper.h
resource/include/InProcClientWrapper.h
resource/include/OCApi.h
resource/include/OCDirectPairing.h [new file with mode: 0644]
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OCProvisioningManager.h
resource/include/OutOfProcClientWrapper.h
resource/provisioning/examples/provisioningclient.cpp
resource/provisioning/src/OCProvisioningManager.cpp
resource/provisioning/unittests/OCProvisioningTest.cpp
resource/src/InProcClientWrapper.cpp
resource/src/OCDirectPairing.cpp [new file with mode: 0644]
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp
resource/src/OCResource.cpp
resource/src/SConscript
resource/unittests/OCPlatformTest.cpp

index 5606598..be68b04 100644 (file)
@@ -1008,6 +1008,7 @@ OCStackResult DPDeviceDiscovery(unsigned short waittime)
         }\r
         else\r
         {\r
+            OCProcess();\r
             nanosleep(&timeout, NULL);\r
         }\r
     }\r
index 5d84295..5b2c1d8 100644 (file)
@@ -91,11 +91,14 @@ lightserver = examples_env.Program('lightserver', 'lightserver.cpp')
 devicediscoveryserver = examples_env.Program('devicediscoveryserver', 'devicediscoveryserver.cpp')
 devicediscoveryclient = examples_env.Program('devicediscoveryclient', 'devicediscoveryclient.cpp')
 threadingsample = examples_env.Program('threadingsample', 'threadingsample.cpp')
+directpairingclient = examples_env.Program('directpairingclient', 'directpairingclient.cpp')
 
 clientjson = examples_env.Install(env.get('BUILD_DIR') + '/resource/examples/',
                                env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_client.dat')
 serverjson = examples_env.Install(env.get('BUILD_DIR') + '/resource/examples/',
                                env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_server.dat')
+directpairingdat = examples_env.Install(env.get('BUILD_DIR') + '/resource/examples/',
+                               env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_client_directpairing.dat')
 Alias("examples", [simpleserver, simpleclient,
                simpleserverHQ, simpleclientHQ,
                fridgeserver, fridgeclient,
@@ -105,7 +108,7 @@ Alias("examples", [simpleserver, simpleclient,
                groupserver, groupclient,
                lightserver,
                devicediscoveryserver, devicediscoveryclient,
-               threadingsample,
-               serverjson, clientjson
+               threadingsample, directpairingclient,
+               serverjson, clientjson, directpairingdat
      ])
 env.AppendTarget('examples')
diff --git a/resource/examples/directpairingclient.cpp b/resource/examples/directpairingclient.cpp
new file mode 100644 (file)
index 0000000..6ab04fe
--- /dev/null
@@ -0,0 +1,411 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <string>
+#include <map>
+#include <cstdlib>
+#include <pthread.h>
+#include <mutex>
+#include <condition_variable>
+
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+#define MAX_URI_LENGTH (64)
+#define MAX_PERMISSION_LENGTH (5)
+#define CREATE (1)
+#define READ (2)
+#define UPDATE (4)
+#define DELETE (8)
+#define NOTIFY (16)
+#define DASH '-'
+#define PREDEFINED_TIMEOUT (10)
+#define MAX_OWNED_DEVICE (10)
+#define TAG  "provisioningclient"
+
+#define JSON_DB_PATH "./oic_svr_db_client.json"
+#define DAT_DB_PATH "./oic_svr_db_client.dat"
+#define DEV_STATUS_ON "DEV_STATUS_ON"
+#define DEV_STATUS_OFF "DEV_STATUS_OFF"
+
+#define DP_DISCOVERY_TIMEOUT 4
+#define DP_PIN_LENGTH 8
+
+#define BOLD_BEGIN    "\033[1m"
+#define RED_BEGIN     "\033[1;31m"
+#define GREEN_BEGIN   "\033[1;92m"
+#define COLOR_END     "\033[0m"
+
+using namespace OC;
+
+static int ask = 1;
+static PairedDevices discoveredDeviceList, pairedDeviceList;
+
+static FILE* client_open(const char* /*fileName*/, const char *mode)
+{
+    return fopen(DAT_DB_PATH, mode);
+}
+
+
+static void printMenu()
+{
+    std::cout << GREEN_BEGIN "Choose an option:" COLOR_END<<std::endl;
+    std::cout << GREEN_BEGIN "# 1 (DP device discovery) : discover Direct-Pairing devices"
+        COLOR_END<<std::endl;
+    std::cout << GREEN_BEGIN "# 2 (start Direct-Pairing) : negotiate DP method & start Direct-Pairin"
+        COLOR_END<<std::endl;
+    std::cout << GREEN_BEGIN "# 3 (list all device) : list all discovered/paired devices"
+        COLOR_END<<std::endl;
+    std::cout << GREEN_BEGIN "# 4 (send data) : send data to device" COLOR_END<<std::endl;
+    std::cout << GREEN_BEGIN "# 9 (quit) : quit test " COLOR_END<<std::endl;
+}
+
+static void printPrompt()
+{
+    std::cout << BOLD_BEGIN "IoTivity-DP#" COLOR_END" ";
+}
+
+static void printDevices(PairedDevices& list)
+{
+    for (size_t i = 0; i < list.size(); i++)
+    {
+        std::cout << "["<< i+1 << "]" << " ID: " << list[i]->getDeviceID() << std::endl;
+    }
+}
+
+static void findCallback(PairedDevices discoveredDevList)
+{
+
+    if (0 == discoveredDevList.size())
+    {
+        std::cout<< "No Direct-pairing Support device Found" << std::endl;
+    }
+    else
+    {
+        std::cout << "Discovered Direct-Pairing Support Device"<< std::endl;
+        discoveredDeviceList = discoveredDevList;
+        printDevices(discoveredDevList);
+    }
+
+    printMenu();
+    printPrompt();
+    fflush(NULL);
+}
+
+static bool printPairingMethod(int choice)
+{
+    if (NULL == discoveredDeviceList[choice])// || false == discoveredDeviceList[choice]->edp)
+    {
+        std::cout<< "Invalid device or Not support direct-pairing..\n\n" << std::endl;
+        return false;
+    }
+
+    auto prms = discoveredDeviceList[choice]->getPairingMethods();
+    if (0 == prms.size())
+    {
+        std::cout << "Not exist any support method..\n\n" << std::endl;
+        return false;
+    }
+
+    bool ret = true;
+    std::cout << "\n* List of supported pairing methods *" << std::endl;
+
+    for (unsigned int i = 0; i < prms.size(); i++)
+    {
+        std::cout<< "[" << i+1 << "]";
+        switch (prms[i])
+        {
+            case DP_PRE_CONFIGURED:
+                std::cout<<"Pre-Configured PIN"<<std::endl;;
+                break;
+            case DP_RANDOM_PIN:
+                std::cout<<"Random PIN"<<std::endl;;
+                break;
+            default:
+                std::cout<<"NOT Allowed ("<< prms[i]<<")"<<std::endl;
+                ret = false;
+                break;
+        }
+        std::cout<<std::endl;
+    }
+
+    return ret;
+}
+
+static void resultCallback(std::shared_ptr<OCDirectPairing> ptr, OCStackResult result)
+{
+
+    if (OC_STACK_OK == result)
+    {
+        std::cout << " Direct-Pairing SUCCESS" << std::endl;
+        std::cout << "Taget Add info:" << ptr->getHost() << std::endl;
+    }
+    else {
+        std::cout <<" Direct-Pairing FAILED" << std::endl;
+    }
+
+    printMenu();
+    printPrompt();
+    fflush(NULL);
+}
+
+static void pairedDevListCB(PairedDevices pairedDevList)
+{
+
+    if (0 == pairedDevList.size())
+    {
+        std::cout << "No Paired Devcie  Found" << std::endl;
+    }
+    else
+    {
+        pairedDeviceList = pairedDevList;
+        printDevices(pairedDevList);
+    }
+
+    printMenu();
+    printPrompt();
+    fflush(NULL);
+}
+
+static void getCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    (void)(headerOptions);
+    try
+    {
+        if (OC_STACK_OK == eCode)
+        {
+            std::cout << "Callback Context for GET query recvd successfully" << std::endl;
+            std::cout << "Resource URI: " << rep.getUri() << std::endl;
+
+            bool state = false;
+            int power = 0;
+            rep.getValue("state", state);
+            rep.getValue("power", power);
+
+            std::cout << "\tstate: " << state << std::endl;
+            std::cout << "\tpower: " << power << std::endl;
+        }
+        else
+        {
+            std::cout << "getCallback Response error: " << eCode << std::endl;
+        }
+    }
+    catch(std::exception& e)
+    {
+        std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
+    }
+}
+
+static bool InputPIN(std::string& pin)
+{
+    std::cout <<"   > Enter PIN Number for authentication (ex - '00000000' [8 digit] ):" ;
+
+    std::cin >> pin;
+
+    if (pin.size() != DP_PIN_LENGTH)
+    {
+        std::cout<<"Invalid PIN"<<std::endl;
+        return false;
+    }
+
+    return true;
+}
+
+int main(void)
+{
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+
+    // Create PlatformConfig object
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+            OC::ModeType::Both,
+            "0.0.0.0",
+            0,
+            OC::QualityOfService::LowQos,
+            &ps
+    };
+
+    OCPlatform::Configure(cfg);
+
+    try
+    {
+        unsigned int choice;
+        for (int out = 0; !out;)
+        {
+            if (ask)
+            {
+                printMenu();
+                printPrompt();
+                fflush(NULL);
+            }
+            std::cin >> choice;
+
+            switch(choice) {
+                case 1:
+                    {
+                        OCStackResult result = OC::OCPlatform::findDirectPairingDevices(
+                                DP_DISCOVERY_TIMEOUT, findCallback);
+
+                        if (OC_STACK_NO_RESOURCE == result)
+                        {
+                            std::cout << "!! No Direct-Pairing Support Device found"<<std::endl;
+                            break;
+                        }
+
+                        if (OC_STACK_OK != result)
+                        {
+                            std::cout << "!!Error - findDirectPairingDevices failed."<<std::endl;
+                        }
+                        ask = 0;
+                        break;
+                    }
+                case 2:
+                    {
+                        unsigned int pMethodIDx = -1;
+                        std::string pin("");
+
+                        std::cout << "- Negotiate DP method & Start Direct-Pairing - ";
+                        std::cout << "* List of  discovered device" << std::endl;
+                        printDevices(discoveredDeviceList);
+                        std::cout << "   > Enter Peer Device Number to initiate Direct-Pairing:" << std::endl;
+                        printPrompt();
+                        std::cin >> choice;
+                        if (choice < 1 || choice > discoveredDeviceList.size())
+                        {
+                            std::cout << "!!Device Number is incorrect, Try Again" << std::endl;
+                            break;
+                        }
+                        OCPrm_t pmSel = DP_NOT_ALLOWED;
+                        choice--;
+                        if (false == printPairingMethod(choice))
+                        {
+                            std::cout << "Target does not support the Direct-Pairing" << std::endl;
+                            break;
+                        }
+
+                        std::cout << " > Enter pairing method: "<< std::endl;
+                        printPrompt();
+                        std::cin >> pMethodIDx;
+                        auto prms = discoveredDeviceList[choice]->getPairingMethods();
+                        if (0 >= pMethodIDx || prms.size() < pMethodIDx)
+                        {
+                            std::cout <<"Invalid mode selection" << std::endl;
+                            break;
+                        }
+
+                        pmSel =  prms[pMethodIDx - 1];
+                        if (false == InputPIN(pin))
+                        {
+                            break;
+                        }
+
+                        OCStackResult result = OC::OCPlatform::doDirectPairing(discoveredDeviceList[choice], pmSel, pin, resultCallback);
+
+                        if (OC_STACK_OK != result)
+                        {
+                            std::cout << "!!Error - doDirectPairing failed." << std::endl;
+                        }
+                        ask = 0;
+                        break;
+                    }
+                case 3:
+                    {
+                        std::cout << "- List all discovered and paired devices) -";
+                        std::cout << "  > List of discovered devices" << std::endl;
+                        printDevices(discoveredDeviceList);
+                        std::cout << std::endl;
+
+                        std::cout << "  > List of paired devices" << std::endl;
+                        OCStackResult result = OC::OCPlatform::getDirectPairedDevices(pairedDevListCB);
+                        printDevices(pairedDeviceList);
+                        std::cout << std::endl;
+
+                        if (OC_STACK_NO_RESOURCE == result)
+                        {
+                            std::cout << "!! No Paired device found"<<std::endl;
+                            break;
+                        }
+                        if (OC_STACK_OK != result)
+                        {
+                            std::cout << "!!Error - getDirectPairedDevices failed."<<std::endl;
+                        }
+                        break;
+                    }
+                case 4:
+                    {
+                        std::cout << "- Send data(GET Request) to device(led server) -" << std::endl;
+                        printDevices(pairedDeviceList);
+                        pairedDeviceList = discoveredDeviceList;
+                        printMenu();
+                        std::cout << "Enter device number to GET data: ";
+                        std::cin >> choice;
+                        choice--;
+
+                        std::vector<std::string> ledTypes = {"core.led"};
+                        std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
+
+                        OCConnectivityType ct = pairedDeviceList[choice]->getConnType();
+
+                        std::cout << "\n\n HOST address is : " << pairedDeviceList[choice]->getHost() << "\n\n";
+                        OCResource::Ptr led = OC::OCPlatform::constructResourceObject(
+                                pairedDeviceList[choice]->getHost(),
+                                "/a/led", ct, false, ledTypes, ifaces);
+
+                        if(!led)
+                        {
+                            std::cout << "Error: Led Object construction returned null" << std::endl;
+                            break;
+                        }
+                        OCStackResult res = led->get(QueryParamsMap(), getCallback);
+
+                        if (OC_STACK_OK != res)
+                        {
+                            std::cout << "Error: get Failed for Led" << std::endl;
+                        }
+                        break;
+                    }
+                case 9:
+                    {
+                        out = 1;
+                        break;
+                    }
+                default:
+                    {
+                        std::cout << GREEN_BEGIN "Wrong Option : Try Again" COLOR_END << std::endl;
+                        printMenu();
+                        printPrompt();
+                        break;
+                    }
+            }
+        }
+    }
+    catch(OCException& e)
+    {
+        oclog() << "Exception in main: "<< e.what();
+    }
+
+    return 0;
+}
diff --git a/resource/examples/oic_svr_db_client_directpairing.dat b/resource/examples/oic_svr_db_client_directpairing.dat
new file mode 100644 (file)
index 0000000..116deb8
Binary files /dev/null and b/resource/examples/oic_svr_db_client_directpairing.dat differ
diff --git a/resource/examples/oic_svr_db_client_directpairing.json b/resource/examples/oic_svr_db_client_directpairing.json
new file mode 100644 (file)
index 0000000..0c83965
--- /dev/null
@@ -0,0 +1,88 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        },\r
+                        {\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        },\r
+                        {\r
+                            "href": "/oic/res/types/d",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        },\r
+                        {\r
+                            "href": "/oic/presence",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/acl",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/cred",\r
+                            "rel": "",\r
+                            "rt": "",\r
+                            "if": ""\r
+                        }\r
+                    ],\r
+                    "permission": 6\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "64706169-7269-6e67-4465-765555494430"\r
+    },\r
+    "pstat": {\r
+        "isop": false,\r
+        "deviceuuid": "64706169-7269-6e67-4465-765555494430",\r
+        "rowneruuid": "64706169-7269-6e67-4465-765555494430",\r
+        "cm": 2,\r
+        "tm": 0,\r
+        "om": 3,\r
+        "sm": 3\r
+        },\r
+    "doxm": {\r
+        "oxms": [0],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": false,\r
+        "deviceuuid": "64706169-7269-6e67-4465-765555494430",\r
+        "devowneruuid": "",\r
+        "rowneruuid": "64706169-7269-6e67-4465-765555494430",\r
+        "dpc": false\r
+    }\r
+}\r
index 6a3d525..0cbfa53 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <memory>
 #include <string>
-
 #include <OCApi.h>
 
 namespace OC
@@ -111,6 +110,14 @@ namespace OC
 
         virtual OCStackResult GetDefaultQos(QualityOfService& qos) = 0;
 
+        virtual OCStackResult FindDirectPairingDevices(unsigned short waittime,
+                        GetDirectPairedCallback& callback) = 0;
+
+        virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& callback) = 0;
+
+        virtual OCStackResult DoDirectPairing(std::shared_ptr<OCDirectPairing> peer, const OCPrm_t& pmSel,
+                const std::string& pinNumber, DirectPairingCallback& resultCallback) = 0;
+
         virtual ~IClientWrapper(){}
     };
 }
index 33d3e22..c13edb1 100644 (file)
@@ -92,6 +92,13 @@ namespace OC
             ObserveCallback callback;
             ObserveContext(ObserveCallback cb) : callback(cb){}
         };
+
+        struct DirectPairingContext
+        {
+            DirectPairingCallback callback;
+            DirectPairingContext(DirectPairingCallback cb) : callback(cb){}
+
+        };
     }
 
     class InProcClientWrapper : public IClientWrapper
@@ -161,12 +168,23 @@ namespace OC
 
         virtual OCStackResult UnsubscribePresence(OCDoHandle handle);
         OCStackResult GetDefaultQos(QualityOfService& QoS);
+
+
+        virtual OCStackResult FindDirectPairingDevices(unsigned short waittime,
+                       GetDirectPairedCallback& callback);
+
+        virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& callback);
+
+        virtual OCStackResult DoDirectPairing(std::shared_ptr<OCDirectPairing> peer, const OCPrm_t& pmSel,
+                const std::string& pinNumber, DirectPairingCallback& resultCallback);
+
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
         OCPayload* assembleSetResourcePayload(const OCRepresentation& attributes);
         OCHeaderOption* assembleHeaderOptions(OCHeaderOption options[],
            const HeaderOptions& headerOptions);
+        void convert(const OCDPDev_t *list, PairedDevices& dpList);
         std::thread m_listeningThread;
         bool m_threadRun;
         std::weak_ptr<std::recursive_mutex> m_csdkLock;
index d124502..7717c86 100644 (file)
@@ -41,6 +41,7 @@ namespace OC
     class OCResource;
     class OCResourceRequest;
     class OCResourceResponse;
+    class OCDirectPairing;
 } // namespace OC
 
 namespace OC
@@ -249,6 +250,8 @@ namespace OC
     // Used in GET, PUT, POST methods on links to other remote resources of a group.
     const std::string GROUP_INTERFACE = "oic.mi.grp";
 
+    //Typedef for list direct paired devices
+    typedef std::vector<std::shared_ptr<OCDirectPairing>> PairedDevices;
 
     typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
 
@@ -277,6 +280,11 @@ namespace OC
 
     typedef std::function<void(const HeaderOptions&,
                                 const OCRepresentation&, const int, const int)> ObserveCallback;
+
+    typedef std::function<void(std::shared_ptr<OCDirectPairing>, OCStackResult)> DirectPairingCallback;
+
+    typedef std::function<void(const PairedDevices&)> GetDirectPairedCallback;
+
 } // namespace OC
 
 #endif
diff --git a/resource/include/OCDirectPairing.h b/resource/include/OCDirectPairing.h
new file mode 100644 (file)
index 0000000..3f27b83
--- /dev/null
@@ -0,0 +1,69 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OC_DIRECT_PAIRING_H_
+#define OC_DIRECT_PAIRING_H_
+#include <OCApi.h>
+
+namespace OC
+{
+    class OCDirectPairing
+    {
+        public:
+            OCDirectPairing(OCDPDev_t *ptr);
+            /**
+             * Function to get the host address of direct pairing device.
+             *
+             * @return Returns host address in the format
+             *           <coaps>:IP:securePort
+             */
+            std::string getHost();
+
+            /**
+             * Function to get the device ID of the direct pairing device.
+             *
+             * @return Returns device ID (UUID)
+             */
+            std::string getDeviceID();
+
+            /**
+             * Function to get the pairing methods supported by direct pairing device.
+             *
+             * @return Returns vector of pairing methods supported.
+             *   DP_NOT_ALLOWED
+             *   DP_PRE_CONFIGURED
+             *   DP_RANDOM_PIN
+             */
+            std::vector<OCPrm_t> getPairingMethods();
+
+            /**
+             * Function to get the connectivity Type.
+             *
+             * @return Returns connectivity Type
+             */
+            OCConnectivityType getConnType();
+
+            OCDPDev_t* getDev();
+
+        private:
+            OCDPDev_t *m_devPtr;
+    };
+}
+#endif //OC_DIRECT_PAIRING_H_
index 2828b9e..37c4b54 100644 (file)
@@ -523,45 +523,45 @@ namespace OC
                         SubscribeCallback presenceHandler);
 
         /**
-        * unsubscribes from a previously subscribed server's presence events. Note that
-        * you may for a short time still receive events from the server since it may take time
-        * for the unsubscribe to take effect.
-        *
-        * @param presenceHandle the handle object provided by the subscribePresence call that
-        *               identifies this subscription.
-        *
-        * @return Returns ::OC_STACK_OK if success.
-        */
+         * unsubscribes from a previously subscribed server's presence events. Note that
+         * you may for a short time still receive events from the server since it may take time
+         * for the unsubscribe to take effect.
+         *
+         * @param presenceHandle the handle object provided by the subscribePresence call that
+         *               identifies this subscription.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
         OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle);
 
         /**
-        * Creates a resource proxy object so that get/put/observe functionality
-        * can be used without discovering the object in advance.  Note that the
-        * consumer of this method needs to provide all of the details required to
-        * correctly contact and observe the object. If the consumer lacks any of
-        * this information, they should discover the resource object normally.
-        * Additionally, you can only create this object if OCPlatform was initialized
-        * to be a Client or Client/Server.  Otherwise, this will return an empty
-        * shared ptr.
-        *
-        * @param host a string containing a resolvable host address of the server
-        *           holding the resource. Currently this should be in the format
-        *           coap://address:port, though in the future, we expect this to
-        *           change to //address:port
-        *
-        * @param uri the rest of the resource's URI that will permit messages to be
-        *           properly routed.  Example: /a/light
-        *
-        * @param connectivityType ::OCConnectivityType type of connectivity indicating the
-        *                           interface. Example: OC_WIFI, OC_ETHERNET, OC_ALL
-        *
-        * @param isObservable a boolean containing whether the resource supports observation
-        *
-        * @param resourceTypes a collection of resource types implemented by the resource
-        *
-        * @param interfaces a collection of interfaces that the resource supports/implements
-        * @return OCResource::Ptr a shared pointer to the new resource object
-        */
+         * Creates a resource proxy object so that get/put/observe functionality
+         * can be used without discovering the object in advance.  Note that the
+         * consumer of this method needs to provide all of the details required to
+         * correctly contact and observe the object. If the consumer lacks any of
+         * this information, they should discover the resource object normally.
+         * Additionally, you can only create this object if OCPlatform was initialized
+         * to be a Client or Client/Server.  Otherwise, this will return an empty
+         * shared ptr.
+         *
+         * @param host a string containing a resolvable host address of the server
+         *           holding the resource. Currently this should be in the format
+         *           coap://address:port, though in the future, we expect this to
+         *           change to //address:port
+         *
+         * @param uri the rest of the resource's URI that will permit messages to be
+         *           properly routed.  Example: /a/light
+         *
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: OC_WIFI, OC_ETHERNET, OC_ALL
+         *
+         * @param isObservable a boolean containing whether the resource supports observation
+         *
+         * @param resourceTypes a collection of resource types implemented by the resource
+         *
+         * @param interfaces a collection of interfaces that the resource supports/implements
+         * @return OCResource::Ptr a shared pointer to the new resource object
+         */
         OCResource::Ptr constructResourceObject(const std::string& host,
                         const std::string& uri,
                         OCConnectivityType connectivityType, bool isObservable,
@@ -569,14 +569,48 @@ namespace OC
                         const std::vector<std::string>& interfaces);
 
         /**
-        * Allows application entity handler to send response to an incoming request.
-        *
-        * @param pResponse OCResourceResponse pointer that will permit to set values related
-        * to resource response.
-        *
-        * @return Returns ::OC_STACK_OK if success.
-        */
+         * Allows application entity handler to send response to an incoming request.
+         *
+         * @param pResponse OCResourceResponse pointer that will permit to set values related
+         * to resource response.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
         OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse);
+
+        /**
+         * Find all the Direct Pairing capable devices.
+         *
+         * @param waittime timeoutbefore the callback is called
+         * @param callback function to callback with discovered devices after timeout
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult findDirectPairingDevices(unsigned short waittime,
+                                     GetDirectPairedCallback callback);
+
+        /**
+         * Get all the Direct paired devices.
+         *
+         * @param callback function to callback with the list of paired devices
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult getDirectPairedDevices(GetDirectPairedCallback callback);
+
+        /**
+         * Perform the Direct Pairing with the selected peer device
+         *
+         * @param peer device to direct pair with
+         * @param pmSel Selected pairing method
+         * @param pinNumber pin to validate peer & perform the direct pairing
+         * @param resultCallback callback function that will get the result of the operation
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel,
+                                     const std::string& pinNumber,
+                                     DirectPairingCallback resultCallback);
     }
 }
 
index 45441fe..51217f0 100644 (file)
@@ -37,6 +37,7 @@
 #include "OCResourceRequest.h"
 #include "OCResourceResponse.h"
 #include "OCRepresentation.h"
+#include "OCDirectPairing.h"
 
 #include "oc_logger.hpp"
 
@@ -232,6 +233,15 @@ namespace OC
 
         std::weak_ptr<std::recursive_mutex> csdkLock();
 
+        OCStackResult findDirectPairingDevices(unsigned short waittime,
+                                         GetDirectPairedCallback callback);
+
+        OCStackResult getDirectPairedDevices(GetDirectPairedCallback callback);
+
+        OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel,
+                                         const std::string& pinNumber,
+                                         DirectPairingCallback resultCallback);
+
     private:
         PlatformConfig m_cfg;
 
index 0a949e3..535572c 100644 (file)
@@ -268,6 +268,17 @@ namespace OC
                     ResultCallBack resultCallback);
 
             /**
+             * API to provision DirectPairing to devices.
+             *
+             * @param pconf pointer to PCONF (Pairing Configuration).
+             * @param resultCallback Callback will be called when provisioning request receives
+             *                           a response from first resource server.
+             * @return  ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult provisionDirectPairing(const OicSecPconf_t *pconf,
+                    ResultCallBack resultCallback);
+
+            /**
              * This method is used to get linked devices' IDs.
              *
              * @param uuidList Information about the list of linked devices uuids.
index 2438cb1..3719a63 100644 (file)
@@ -123,6 +123,18 @@ namespace OC
 
         virtual OCStackResult GetDefaultQos(QualityOfService& /*QoS*/)
             {return OC_STACK_NOTIMPL;}
+
+        virtual OCStackResult FindDirectPairingDevices(unsigned short /*waittime*/,
+                       GetDirectPairedCallback& /*callback*/)
+            {return OC_STACK_NOTIMPL;}
+
+        virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& /*callback*/)
+            {return OC_STACK_NOTIMPL;}
+
+        virtual OCStackResult DoDirectPairing(std::shared_ptr<OCDirectPairing> /*peer*/,
+                const OCPrm_t& /*pmSel*/,
+                const std::string& /*pinNumber*/, DirectPairingCallback& /*resultCallback*/)
+            {return OC_STACK_NOTIMPL;}
     };
 }
 
index b2c9825..ad53059 100644 (file)
 
 #define DISCOVERY_TIMEOUT 5
 
+static const OicSecPrm_t  SUPPORTED_PRMS[1] =
+{
+    PRM_PRE_CONFIGURED,
+};
+
 using namespace OC;
 
 DeviceList_t pUnownedDevList, pOwnedDevList;
 static int transferDevIdx, ask = 1;
+static OicSecPconf_t g_pconf;
 
 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
 {
@@ -79,8 +85,9 @@ void printMenu()
     std::cout << "   7. Unlink Devices"<<std::endl;
     std::cout << "   8. Remove Device"<<std::endl;
     std::cout << "   9. Get Linked Devices"<<std::endl;
-    std::cout << "   10. Get Device Status"<<std::endl;
-    std::cout << "   11. Exit loop"<<std::endl;
+    std::cout << "  10. Get Device Status"<<std::endl;
+    std::cout << "  11. Provision Direct-Pairing Configuration"<<std::endl;
+    std::cout << "  12. Exit loop"<<std::endl;
 }
 
 void moveTransferredDevice()
@@ -504,6 +511,196 @@ static int InputCredentials(Credential &cred)
    return 0;
 }
 
+static void deletePconf()
+{
+    OICFree(g_pconf.prm);
+    //free pdacl
+    OicSecPdAcl_t* acl = g_pconf.pdacls;
+    if (acl)
+    {
+        /* Clean Resources */
+        for (unsigned int i = 0; i < (acl)->resourcesLen; i++)
+        {
+            OICFree((acl)->resources[i]);
+        }
+        OICFree((acl)->resources);
+
+        /* Clean ACL node itself */
+        /* Required only if acl was created in heap */
+        OICFree((acl));
+    }
+    memset(&g_pconf, 0, sizeof(OicSecPconf_t));
+}
+
+static OicSecPdAcl_t* InputPdACL()
+{
+    int ret;
+    char *temp_rsc, *temp_pms;
+
+    printf("******************************************************************************\n");
+    printf("-Set ACL policy for target DP device\n");
+    printf("******************************************************************************\n");
+
+    OicSecPdAcl_t *acl = (OicSecPdAcl_t *)OICCalloc(1,sizeof(OicSecPdAcl_t));
+    if (NULL == acl)
+    {
+        OIC_LOG(ERROR, TAG, "Error while memory allocation");
+        return NULL;
+    }
+
+    //Set Resource.
+    printf("Num. of Resource : ");
+    ret = scanf("%zu", &acl->resourcesLen);
+    if ((1 != ret) || (acl->resourcesLen <= 0 || acl->resourcesLen > 50))
+    {
+        printf("Error while input\n");
+        OICFree(acl);
+        return NULL;
+    }
+    printf("-URI of resource\n");
+    printf("ex)/oic/sh/temp/0 (Max_URI_Length: 64 Byte )\n");
+    acl->resources = (char **)OICCalloc(acl->resourcesLen, sizeof(char *));
+    if (NULL == acl->resources)
+    {
+        OIC_LOG(ERROR, TAG, "Error while memory allocation");
+        OICFree(acl);
+        return NULL;
+    }
+    for (size_t i = 0; i < acl->resourcesLen; i++)
+    {
+        printf("[%zu]Resource : ", i + 1);
+        ret = scanf("%64ms", &temp_rsc);
+        if (1 != ret)
+        {
+            printf("Error while input\n");
+            OICFree(acl->resources);
+            OICFree(acl);
+            return NULL;
+        }
+
+        acl->resources[i] = OICStrdup(temp_rsc);
+        OICFree(temp_rsc);
+        if (NULL == acl->resources[i])
+        {
+            OIC_LOG(ERROR, TAG, "Error while memory allocation");
+            OICFree(acl->resources);
+            OICFree(acl);
+            return NULL;
+        }
+    }
+
+    // Set Permission
+    do
+    {
+        printf("-Set the permission(C,R,U,D,N)\n");
+        printf("ex) CRUDN, CRU_N,..(5 Charaters)\n");
+        printf("Permission : ");
+        ret = scanf("%5ms", &temp_pms);
+        if (1 != ret)
+        {
+            printf("Error while input\n");
+            OICFree(acl->resources);
+            OICFree(acl);
+            return NULL;
+        }
+        ret = CalculateAclPermission(temp_pms, &(acl->permission));
+        OICFree(temp_pms);
+    } while (0 != ret );
+
+    return acl;
+}
+
+void provisionDirectPairingCB(PMResultList_t *result, int hasError)
+{
+    if (hasError)
+    {
+        std::cout << "Error in provisioning operation!"<<std::endl;
+    }
+    else
+    {
+        std::cout<< "\nReceived provisioning results: Direct Pairing is successful ";
+        for (unsigned int i = 0; i < result->size(); i++)
+        {
+            std::cout << "Result is = " << result->at(i).res <<" for device ";
+            printUuid(result->at(i).deviceId);
+        }
+
+        delete result;
+    }
+    deletePconf();
+    printMenu();
+    ask = 1;
+}
+
+static void provisionDP(int dev_num)
+{
+    OCStackResult rst;
+    std::string pin("");
+
+    // set enable dp
+    g_pconf.edp = true;
+
+    // set default supported PRM types
+    g_pconf.prmLen = sizeof(SUPPORTED_PRMS)/sizeof(OicSecPrm_t);
+    g_pconf.prm = (OicSecPrm_t *)OICCalloc(g_pconf.prmLen, sizeof(OicSecPrm_t));
+    if(g_pconf.prm)
+    {
+        for (size_t i=0; i < g_pconf.prmLen; i++)
+        {
+            g_pconf.prm[i] = SUPPORTED_PRMS[i];
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "create prm error return");
+        goto PVDP_ERROR;
+    }
+
+    std::cout << "Enter PIN to be configured: ";
+    while (1)
+    {
+        std::cin >> pin;
+        if (pin.length() == DP_PIN_LENGTH)
+        {
+            break;
+        }
+        else
+        {
+            std::cout << "PIN length should be 8, Enter again: ";
+        }
+    }
+
+    memcpy(g_pconf.pin.val, pin.c_str(), DP_PIN_LENGTH);
+
+    // set default pdacl
+
+    g_pconf.pdacls = InputPdACL();
+    if(!g_pconf.pdacls)
+    {
+        OIC_LOG(ERROR, TAG, "InputPdACL error return");
+        goto PVDP_ERROR;
+    }
+
+    // call |OCProvisionDirectPairing| API actually
+    // calling this API with callback actually acts like blocking
+    // for error checking, the return value saved and printed
+    rst = pOwnedDevList[dev_num-1]->provisionDirectPairing(&g_pconf, provisionDirectPairingCB);
+    if(OC_STACK_OK != rst)
+    {
+        OIC_LOG_V(ERROR, TAG, "OCProvisionDirectPairing API error: %d", rst);
+        if (OC_STACK_UNAUTHORIZED_REQ == rst)
+        {
+            OIC_LOG(ERROR, TAG, "Target Server NOT Support Direct-Pairing !!! (DPC == false)");
+        }
+        goto PVDP_ERROR;
+    }
+    return;
+
+PVDP_ERROR:
+    deletePconf();  // after here |acl| points nothing
+    ask = 1;
+}
+
 int main(void)
 {
     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
@@ -890,6 +1087,36 @@ int main(void)
                     }
 
                 case 11:
+                    {
+                        unsigned int devNum;
+
+                        if (!pOwnedDevList.size())
+                        {
+                            std::cout <<"There are no Owned devices yet,"
+                                " may need to discover"<<std::endl;
+                            break;
+                        }
+
+                        for (unsigned int i = 0; i < pOwnedDevList.size(); i++ )
+                        {
+                            std::cout << i+1 << ": "<< pOwnedDevList[i]->getDeviceID() <<" From IP:";
+                            std::cout << pOwnedDevList[i]->getDevAddr() <<std::endl;
+                        }
+
+                        std::cout <<"Select device number: "<<std::endl;
+                        std::cin >> devNum;
+                        if (devNum > pOwnedDevList.size())
+                        {
+                            std::cout <<"Invalid device number"<<std::endl;
+                            break;
+                        }
+
+                        ask = 0;
+                        provisionDP(devNum);
+
+                        break;
+                    }
+                case 12:
                 default:
                     out = 1;
                     break;
index 8a2c076..17ebd68 100644 (file)
@@ -30,7 +30,7 @@ namespace OC
         OCStackResult result;
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCInitPM(dbPath.c_str());
@@ -52,7 +52,7 @@ namespace OC
         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
         auto cLock = csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCDiscoverUnownedDevices(timeout, &pDevList);
@@ -91,7 +91,7 @@ namespace OC
         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
         auto cLock = csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCDiscoverOwnedDevices(timeout, &pDevList);
@@ -124,13 +124,13 @@ namespace OC
     OCStackResult OCSecure::setOwnerTransferCallbackData(OicSecOxm_t oxm,
             OTMCallbackData_t* callbackData, InputPinCallback inputPin)
     {
-        if(NULL == callbackData || oxm >= OIC_OXM_COUNT)
+        if (NULL == callbackData || oxm >= OIC_OXM_COUNT)
         {
             oclog() <<"Invalid callbackData or OXM type";
             return OC_STACK_INVALID_PARAM;
         }
 
-        if((OIC_RANDOM_DEVICE_PIN == oxm) && !inputPin)
+        if ((OIC_RANDOM_DEVICE_PIN == oxm) && !inputPin)
         {
             oclog() <<"for OXM type DEVICE_PIN, inputPin callback can't be null";
             return OC_STACK_INVALID_PARAM;
@@ -139,11 +139,11 @@ namespace OC
         OCStackResult result;
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCSetOwnerTransferCallbackData(oxm, callbackData);
-            if(result == OC_STACK_OK && (OIC_RANDOM_DEVICE_PIN == oxm))
+            if (result == OC_STACK_OK && (OIC_RANDOM_DEVICE_PIN == oxm))
             {
                 SetInputPinCB(inputPin);
             }
@@ -167,7 +167,7 @@ namespace OC
         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
         auto cLock = csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
 
@@ -207,7 +207,7 @@ namespace OC
 
     OCStackResult OCSecure::setDisplayPinCB(GeneratePinCallback displayPin)
     {
-        if(!displayPin)
+        if (!displayPin)
         {
             oclog() <<"displayPin can't be null";
             return OC_STACK_INVALID_PARAM;
@@ -216,7 +216,7 @@ namespace OC
         OCStackResult result = OC_STACK_OK;
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             SetGeneratePinCB(displayPin);
@@ -269,7 +269,7 @@ namespace OC
 
     OCSecureResource::~OCSecureResource()
     {
-        if(devPtr)
+        if (devPtr)
         {
             OCDeleteDiscoveredDevices(devPtr);
         }
@@ -277,7 +277,7 @@ namespace OC
 
     OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() <<"Result callback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -286,7 +286,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -305,12 +305,12 @@ namespace OC
     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
             ResultCallBack resultCallback)
     {
-        if(!acl)
+        if (!acl)
         {
             oclog() <<"ACL can't be null";
             return OC_STACK_INVALID_PARAM;
         }
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() <<"result callback can not be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -319,7 +319,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -339,7 +339,7 @@ namespace OC
     OCStackResult OCSecureResource::provisionCredentials(const Credential &cred,
             const OCSecureResource &device2, ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result calback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -348,7 +348,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -371,7 +371,7 @@ namespace OC
             const OicSecAcl_t* acl1, const OCSecureResource &device2, const OicSecAcl_t* acl2,
             ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result callback can not be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -380,7 +380,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -403,7 +403,7 @@ namespace OC
     OCStackResult OCSecureResource::unlinkDevices(const OCSecureResource &device2,
             ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result calback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -412,7 +412,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -432,7 +432,7 @@ namespace OC
     OCStackResult OCSecureResource::removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery,
             ResultCallBack resultCallback)
     {
-        if(!resultCallback)
+        if (!resultCallback)
         {
             oclog() << "Result calback can't be null";
             return OC_STACK_INVALID_CALLBACK;
@@ -441,7 +441,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             ProvisionContext* context = new ProvisionContext(resultCallback);
 
@@ -465,7 +465,7 @@ namespace OC
         auto devUuid = devPtr->doxm->deviceID;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
 
@@ -488,6 +488,40 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecureResource::provisionDirectPairing( const OicSecPconf_t* pconf,
+            ResultCallBack resultCallback)
+    {
+        if (!pconf)
+        {
+            oclog() <<"PCONF can't be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCProvisionDirectPairing(static_cast<void*>(context),
+                    devPtr, const_cast<OicSecPconf_t*>(pconf),
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
     std::string OCSecureResource::getDeviceID()
     {
         std::ostringstream deviceId("");
@@ -498,6 +532,7 @@ namespace OC
         if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
         {
             deviceId << devID;
+            free(devID);
         }
         else
         {
index 38e27bf..9e44e06 100644 (file)
@@ -173,4 +173,23 @@ namespace OCProvisioningTest
         OICFree(acl2);
     }
 
+    TEST(ProvisionDirectPairingTest, ProvisionDirectPairingTestNullPconf)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, device.provisionDirectPairing(nullptr, resultCallback));
+    }
+
+    TEST(ProvisionDirectPairingTest, ProvisionDirectPairingTestNullCallback)
+    {
+        OCSecureResource device;
+        OicSecPconf_t *pconf = (OicSecPconf_t *)OICCalloc(1,sizeof(OicSecPconf_t));
+        EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.provisionDirectPairing(pconf, nullptr));
+        OICFree(pconf);
+    }
+
+    TEST(ProvisionDirectPairingTest, ProvisionDirectPairingTestNullCallbackNUllPconf)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, device.provisionDirectPairing(nullptr, nullptr));
+    }
 }
index 23752b9..ae3e0de 100644 (file)
@@ -37,7 +37,7 @@ namespace OC
         // if the config type is server, we ought to never get called.  If the config type
         // is both, we count on the server to run the thread and do the initialize
 
-        if(m_cfg.mode == ModeType::Client)
+        if (m_cfg.mode == ModeType::Client)
         {
             OCTransportFlags serverFlags =
                             static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
@@ -45,7 +45,7 @@ namespace OC
                             static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
             OCStackResult result = OCInit1(OC_CLIENT, serverFlags, clientFlags);
 
-            if(OC_STACK_OK != result)
+            if (OC_STACK_OK != result)
             {
                 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
             }
@@ -57,7 +57,7 @@ namespace OC
 
     InProcClientWrapper::~InProcClientWrapper()
     {
-        if(m_threadRun && m_listeningThread.joinable())
+        if (m_threadRun && m_listeningThread.joinable())
         {
             m_threadRun = false;
             m_listeningThread.join();
@@ -65,7 +65,7 @@ namespace OC
 
         // only stop if we are the ones who actually called 'init'.  We are counting
         // on the server to do the stop.
-        if(m_cfg.mode == ModeType::Client)
+        if (m_cfg.mode == ModeType::Client)
         {
             OCStop();
         }
@@ -77,7 +77,7 @@ namespace OC
         {
             OCStackResult result;
             auto cLock = m_csdkLock.lock();
-            if(cLock)
+            if (cLock)
             {
                 std::lock_guard<std::recursive_mutex> lock(*cLock);
                 result = OCProcess();
@@ -87,7 +87,7 @@ namespace OC
                 result = OC_STACK_ERROR;
             }
 
-            if(result != OC_STACK_OK)
+            if (result != OC_STACK_OK)
             {
                 // TODO: do something with result if failed?
             }
@@ -99,7 +99,7 @@ namespace OC
 
     OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
     {
-        if(clientResponse->payload == nullptr ||
+        if (clientResponse->payload == nullptr ||
                 (
                     clientResponse->payload->type != PAYLOAD_TYPE_DEVICE &&
                     clientResponse->payload->type != PAYLOAD_TYPE_PLATFORM &&
@@ -116,7 +116,7 @@ namespace OC
         //OCPayloadDestroy(clientResponse->payload);
 
         std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
-        if(it == oc.representations().end())
+        if (it == oc.representations().end())
         {
             return OCRepresentation();
         }
@@ -140,7 +140,7 @@ namespace OC
         ClientCallbackContext::ListenContext* context =
             static_cast<ClientCallbackContext::ListenContext*>(ctx);
 
-        if(clientResponse->result != OC_STACK_OK)
+        if (clientResponse->result != OC_STACK_OK)
         {
             oclog() << "listenCallback(): failed to create resource. clientResponse: "
                     << clientResponse->result
@@ -149,7 +149,7 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
-        if(!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
+        if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
         {
             oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
                 << std::flush;
@@ -158,7 +158,7 @@ namespace OC
 
         auto clientWrapper = context->clientWrapper.lock();
 
-        if(!clientWrapper)
+        if (!clientWrapper)
         {
             oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
                     << std::flush;
@@ -241,7 +241,7 @@ namespace OC
             OCConnectivityType connectivityType,
             FindCallback& callback, QualityOfService QoS)
     {
-        if(!callback)
+        if (!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -259,7 +259,7 @@ namespace OC
             );
 
         auto cLock = m_csdkLock.lock();
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCDoResource(nullptr, OC_REST_DISCOVER,
@@ -355,7 +355,7 @@ namespace OC
             FindDeviceCallback& callback,
             QualityOfService QoS)
     {
-        if(!callback)
+        if (!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -372,7 +372,7 @@ namespace OC
                 );
 
         auto cLock = m_csdkLock.lock();
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCDoResource(nullptr, OC_REST_DISCOVER,
@@ -393,7 +393,7 @@ namespace OC
     void parseServerHeaderOptions(OCClientResponse* clientResponse,
                     HeaderOptions& serverHeaderOptions)
     {
-        if(clientResponse)
+        if (clientResponse)
         {
             // Parse header options from server
             uint16_t optionID;
@@ -426,7 +426,7 @@ namespace OC
         OCRepresentation rep;
         HeaderOptions serverHeaderOptions;
         OCStackResult result = clientResponse->result;
-        if(result == OC_STACK_OK)
+        if (result == OC_STACK_OK)
         {
             parseServerHeaderOptions(clientResponse, serverHeaderOptions);
             try
@@ -450,7 +450,7 @@ namespace OC
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         GetCallback& callback, QualityOfService QoS)
     {
-        if(!callback)
+        if (!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -467,7 +467,7 @@ namespace OC
 
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
@@ -524,13 +524,13 @@ namespace OC
     std::string InProcClientWrapper::assembleSetResourceUri(std::string uri,
         const QueryParamsMap& queryParams)
     {
-        if(uri.back() == '/')
+        if (uri.back() == '/')
         {
             uri.resize(uri.size()-1);
         }
 
         ostringstream paramsList;
-        if(queryParams.size() > 0)
+        if (queryParams.size() > 0)
         {
             paramsList << '?';
         }
@@ -541,7 +541,7 @@ namespace OC
         }
 
         std::string queryString = paramsList.str();
-        if(queryString.back() == ';')
+        if (queryString.back() == ';')
         {
             queryString.resize(queryString.size() - 1);
         }
@@ -569,7 +569,7 @@ namespace OC
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PostCallback& callback, QualityOfService QoS)
     {
-        if(!callback)
+        if (!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -585,7 +585,7 @@ namespace OC
 
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
@@ -615,7 +615,7 @@ namespace OC
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         PutCallback& callback, QualityOfService QoS)
     {
-        if(!callback)
+        if (!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -631,7 +631,7 @@ namespace OC
 
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCDoHandle handle;
@@ -663,7 +663,7 @@ namespace OC
             static_cast<ClientCallbackContext::DeleteContext*>(ctx);
         HeaderOptions serverHeaderOptions;
 
-        if(clientResponse->result == OC_STACK_OK)
+        if (clientResponse->result == OC_STACK_OK)
         {
             parseServerHeaderOptions(clientResponse, serverHeaderOptions);
         }
@@ -679,7 +679,7 @@ namespace OC
         DeleteCallback& callback,
         QualityOfService /*QoS*/)
     {
-        if(!callback)
+        if (!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -694,7 +694,7 @@ namespace OC
 
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             OCHeaderOption options[MAX_HEADER_OPTIONS];
 
@@ -728,7 +728,7 @@ namespace OC
         HeaderOptions serverHeaderOptions;
         uint32_t sequenceNumber = clientResponse->sequenceNumber;
         OCStackResult result = clientResponse->result;
-        if(clientResponse->result == OC_STACK_OK)
+        if (clientResponse->result == OC_STACK_OK)
         {
             parseServerHeaderOptions(clientResponse, serverHeaderOptions);
             try
@@ -743,7 +743,7 @@ namespace OC
         std::thread exec(context->callback, serverHeaderOptions, attrs,
                     result, sequenceNumber);
         exec.detach();
-        if(sequenceNumber == OC_OBSERVE_DEREGISTER)
+        if (sequenceNumber == OC_OBSERVE_DEREGISTER)
         {
             return OC_STACK_DELETE_TRANSACTION;
         }
@@ -756,7 +756,7 @@ namespace OC
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
         ObserveCallback& callback, QualityOfService QoS)
     {
-        if(!callback)
+        if (!callback)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -788,7 +788,7 @@ namespace OC
 
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
@@ -821,7 +821,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCHeaderOption options[MAX_HEADER_OPTIONS];
@@ -863,7 +863,7 @@ namespace OC
         const std::string& host, const std::string& resourceType,
         OCConnectivityType connectivityType, SubscribeCallback& presenceHandler)
     {
-        if(!presenceHandler)
+        if (!presenceHandler)
         {
             return OC_STACK_INVALID_PARAM;
         }
@@ -882,12 +882,12 @@ namespace OC
         std::ostringstream os;
         os << host << OC_RSRVD_PRESENCE_URI;
 
-        if(!resourceType.empty())
+        if (!resourceType.empty())
         {
             os << "?rt=" << resourceType;
         }
 
-        if(!cLock)
+        if (!cLock)
         {
             delete ctx;
             return OC_STACK_ERROR;
@@ -904,7 +904,7 @@ namespace OC
         OCStackResult result;
         auto cLock = m_csdkLock.lock();
 
-        if(cLock)
+        if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             result = OCCancel(handle, OC_LOW_QOS, NULL, 0);
@@ -928,7 +928,7 @@ namespace OC
     {
         int i = 0;
 
-        if( headerOptions.size() == 0)
+        if ( headerOptions.size() == 0)
         {
             return nullptr;
         }
@@ -944,4 +944,144 @@ namespace OC
 
         return options;
     }
+
+    std::shared_ptr<OCDirectPairing> cloneDevice(const OCDPDev_t* dev)
+    {
+        if (!dev)
+        {
+            return nullptr;
+        }
+
+        OCDPDev_t* result = new OCDPDev_t(*dev);
+        result->prm = new OCPrm_t[dev->prmLen];
+        memcpy(result->prm, dev->prm, sizeof(OCPrm_t)*dev->prmLen);
+        return std::shared_ptr<OCDirectPairing>(new OCDirectPairing(result));
+    }
+
+    void InProcClientWrapper::convert(const OCDPDev_t *list, PairedDevices& dpList)
+    {
+        while(list)
+        {
+            dpList.push_back(cloneDevice(list));
+            list = list->next;
+        }
+    }
+
+    OCStackResult InProcClientWrapper::FindDirectPairingDevices(unsigned short waittime,
+            GetDirectPairedCallback& callback)
+    {
+        if (!callback || 0 == waittime)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        const OCDPDev_t *list = nullptr;
+        PairedDevices dpDeviceList;
+
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+
+            list = OCDiscoverDirectPairingDevices(waittime);
+            if (NULL == list)
+            {
+                result = OC_STACK_NO_RESOURCE;
+                oclog() << "findDirectPairingDevices(): No device found for direct pairing"
+                    << std::flush;
+            }
+            else {
+                convert(list, dpDeviceList);
+                std::thread exec(callback, dpDeviceList);
+                exec.detach();
+                result = OC_STACK_OK;
+            }
+        }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+    OCStackResult InProcClientWrapper::GetDirectPairedDevices(GetDirectPairedCallback& callback)
+    {
+        if (!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        const OCDPDev_t *list = nullptr;
+        PairedDevices dpDeviceList;
+
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+
+            list = OCGetDirectPairedDevices();
+            if (NULL == list)
+            {
+                result = OC_STACK_NO_RESOURCE;
+                oclog() << "findDirectPairingDevices(): No device found for direct pairing"
+                    << std::flush;
+            }
+            else {
+                convert(list, dpDeviceList);
+                std::thread exec(callback, dpDeviceList);
+                exec.detach();
+                result = OC_STACK_OK;
+            }
+        }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+    void directPairingCallback(void *ctx, OCDPDev_t *peer,
+            OCStackResult result)
+    {
+
+        ClientCallbackContext::DirectPairingContext* context =
+            static_cast<ClientCallbackContext::DirectPairingContext*>(ctx);
+
+        std::thread exec(context->callback, cloneDevice(peer), result);
+        exec.detach();
+    }
+
+    OCStackResult InProcClientWrapper::DoDirectPairing(std::shared_ptr<OCDirectPairing> peer,
+            const OCPrm_t& pmSel, const std::string& pinNumber, DirectPairingCallback& callback)
+    {
+        if (!peer || !callback)
+        {
+            oclog() << "Invalid parameters" << std::flush;
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        ClientCallbackContext::DirectPairingContext* context =
+            new ClientCallbackContext::DirectPairingContext(callback);
+
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDoDirectPairing(static_cast<void*>(context), peer->getDev(),
+                    pmSel, const_cast<char*>(pinNumber.c_str()), directPairingCallback);
+        }
+        else
+        {
+            delete context;
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
 }
diff --git a/resource/src/OCDirectPairing.cpp b/resource/src/OCDirectPairing.cpp
new file mode 100644 (file)
index 0000000..4e50ac7
--- /dev/null
@@ -0,0 +1,85 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "OCDirectPairing.h"
+#include <iomanip>
+
+namespace OC
+{
+    static const char COAP[] = "coap://";
+    static const char COAPS[] = "coaps://";
+    static const int UUID_LENGTH = (128/8); //UUID length
+
+    OCDirectPairing::OCDirectPairing(OCDPDev_t *ptr):m_devPtr(ptr)
+    {
+    }
+
+    std::string OCDirectPairing::getHost()
+    {
+        bool ipv6 = false;
+        std::ostringstream host("");
+        if (m_devPtr->connType & CT_IP_USE_V6)
+        {
+            ipv6 = true;
+        }
+
+        host << COAPS << (ipv6?"[":"") << m_devPtr->endpoint.addr;
+        host << (ipv6?"]:":":") << m_devPtr->securePort;
+
+        return host.str();
+    }
+
+    std::string OCDirectPairing::getDeviceID()
+    {
+        std::ostringstream deviceId("");
+
+        for (int i = 0; i < UUID_LENGTH; i++)
+        {
+            if (i == 4 || i == 6 || i == 8 || i == 10)
+            {
+                deviceId << '-';
+            }
+            deviceId << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned>(m_devPtr->deviceID.id[i]);
+        }
+
+        return deviceId.str();
+    }
+
+    std::vector<OCPrm_t> OCDirectPairing::getPairingMethods()
+    {
+        std::vector<OCPrm_t> prms;
+
+        for (size_t i = 0; i < m_devPtr->prmLen; i++)
+        {
+            prms.push_back(m_devPtr->prm[i]);
+        }
+        return prms;
+    }
+
+    OCConnectivityType OCDirectPairing::getConnType()
+    {
+        return m_devPtr->connType;
+    }
+
+    OCDPDev_t* OCDirectPairing::getDev()
+    {
+        return m_devPtr;
+    }
+}
index e2e7aa5..b722750 100644 (file)
@@ -43,7 +43,7 @@ namespace OC
         }
 
         OCStackResult notifyAllObservers(OCResourceHandle resourceHandle,
-                                                QualityOfService QoS)
+                                     QualityOfService QoS)
         {
             return OCPlatform_impl::Instance().notifyAllObservers(resourceHandle, QoS);
         }
@@ -54,52 +54,52 @@ namespace OC
         }
 
         OCStackResult notifyListOfObservers(OCResourceHandle resourceHandle,
-                                                ObservationIds& observationIds,
-                                                const std::shared_ptr<OCResourceResponse> pResponse)
+                                     ObservationIds& observationIds,
+                                     const std::shared_ptr<OCResourceResponse> pResponse)
         {
             return OCPlatform_impl::Instance().notifyListOfObservers(resourceHandle,
-                                                observationIds, pResponse);
+                                     observationIds, pResponse);
         }
 
         OCStackResult notifyListOfObservers(OCResourceHandle resourceHandle,
-                                                ObservationIds& observationIds,
-                                                const std::shared_ptr<OCResourceResponse> pResponse,
-                                                QualityOfService QoS)
+                                     ObservationIds& observationIds,
+                                     const std::shared_ptr<OCResourceResponse> pResponse,
+                                     QualityOfService QoS)
         {
             return OCPlatform_impl::Instance().notifyListOfObservers(resourceHandle,
-                                                    observationIds, pResponse, QoS);
+                                     observationIds, pResponse, QoS);
         }
 
         OCResource::Ptr constructResourceObject(const std::string& host,
-                                                const std::string& uri,
-                                                OCConnectivityType connectivityType,
-                                                bool isObservable,
-                                                const std::vector<std::string>& resourceTypes,
-                                                const std::vector<std::string>& interfaces)
+                                     const std::string& uri,
+                                     OCConnectivityType connectivityType,
+                                     bool isObservable,
+                                     const std::vector<std::string>& resourceTypes,
+                                     const std::vector<std::string>& interfaces)
         {
             return OCPlatform_impl::Instance().constructResourceObject(host,
-                                                uri, connectivityType,
-                                                isObservable,
-                                                resourceTypes, interfaces);
+                                     uri, connectivityType,
+                                     isObservable,
+                                     resourceTypes, interfaces);
         }
 
         OCStackResult findResource(const std::string& host,
-                                            const std::string& resourceName,
-                                            OCConnectivityType connectivityType,
-                                            FindCallback resourceHandler)
+                                 const std::string& resourceName,
+                                 OCConnectivityType connectivityType,
+                                 FindCallback resourceHandler)
         {
             return OCPlatform_impl::Instance().findResource(host, resourceName,
-                                    connectivityType, resourceHandler);
+                                 connectivityType, resourceHandler);
         }
 
         OCStackResult findResource(const std::string& host,
-                                            const std::string& resourceName,
-                                            OCConnectivityType connectivityType,
-                                            FindCallback resourceHandler,
-                                            QualityOfService QoS)
+                                 const std::string& resourceName,
+                                 OCConnectivityType connectivityType,
+                                 FindCallback resourceHandler,
+                                 QualityOfService QoS)
         {
             return OCPlatform_impl::Instance().findResource(host, resourceName,
-                                    connectivityType, resourceHandler, QoS);
+                                 connectivityType, resourceHandler, QoS);
         }
 
         OCStackResult findResource(const std::string& host,
@@ -124,57 +124,57 @@ namespace OC
         }
 
         OCStackResult getDeviceInfo(const std::string& host,
-                                            const std::string& deviceURI,
-                                            OCConnectivityType connectivityType,
-                                            FindDeviceCallback deviceInfoHandler)
+                                 const std::string& deviceURI,
+                                 OCConnectivityType connectivityType,
+                                 FindDeviceCallback deviceInfoHandler)
         {
             return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI,
-                   connectivityType, deviceInfoHandler);
+                                 connectivityType, deviceInfoHandler);
         }
 
         OCStackResult getDeviceInfo(const std::string& host,
-                                            const std::string& deviceURI,
-                                            OCConnectivityType connectivityType,
-                                            FindDeviceCallback deviceInfoHandler,
-                                            QualityOfService QoS)
+                                 const std::string& deviceURI,
+                                 OCConnectivityType connectivityType,
+                                 FindDeviceCallback deviceInfoHandler,
+                                 QualityOfService QoS)
         {
             return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI, connectivityType,
-                    deviceInfoHandler, QoS);
+                                 deviceInfoHandler, QoS);
         }
 
         OCStackResult getPlatformInfo(const std::string& host,
-                                                const std::string& platformURI,
-                                                OCConnectivityType connectivityType,
-                                                FindPlatformCallback platformInfoHandler)
+                                 const std::string& platformURI,
+                                 OCConnectivityType connectivityType,
+                                 FindPlatformCallback platformInfoHandler)
         {
             return OCPlatform_impl::Instance().getPlatformInfo(host, platformURI,
-                   connectivityType, platformInfoHandler);
+                                 connectivityType, platformInfoHandler);
         }
 
         OCStackResult getPlatformInfo(const std::string& host,
-                                                const std::string& platformURI,
-                                                OCConnectivityType connectivityType,
-                                                FindPlatformCallback platformInfoHandler,
-                                                QualityOfService QoS)
+                                 const std::string& platformURI,
+                                 OCConnectivityType connectivityType,
+                                 FindPlatformCallback platformInfoHandler,
+                                 QualityOfService QoS)
         {
             return OCPlatform_impl::Instance().getPlatformInfo(host, platformURI, connectivityType,
-                    platformInfoHandler, QoS);
+                                 platformInfoHandler, QoS);
         }
 
         OCStackResult registerResource(OCResourceHandle& resourceHandle,
-                                                std::string& resourceURI,
-                                                const std::string& resourceTypeName,
-                                                const std::string& resourceInterface,
-                                                EntityHandler entityHandler,
-                                                uint8_t resourceProperty)
+                                 std::string& resourceURI,
+                                 const std::string& resourceTypeName,
+                                 const std::string& resourceInterface,
+                                 EntityHandler entityHandler,
+                                 uint8_t resourceProperty)
         {
             return OCPlatform_impl::Instance().registerResource(resourceHandle, resourceURI,
-                                                resourceTypeName, resourceInterface,
-                                                entityHandler, resourceProperty);
+                                 resourceTypeName, resourceInterface,
+                                 entityHandler, resourceProperty);
         }
 
         OCStackResult registerResource(OCResourceHandle& resourceHandle,
-                                                const std::shared_ptr< OCResource > resource)
+                                 const std::shared_ptr< OCResource > resource)
         {
             return OCPlatform_impl::Instance().registerResource(resourceHandle, resource);
         }
@@ -195,42 +195,41 @@ namespace OC
         }
 
         OCStackResult unbindResource(OCResourceHandle collectionHandle,
-                                                OCResourceHandle resourceHandle)
+                                 OCResourceHandle resourceHandle)
         {
             return OCPlatform_impl::Instance().unbindResource(collectionHandle, resourceHandle);
         }
 
         OCStackResult unbindResources(const OCResourceHandle collectionHandle,
-                                                const std::vector<OCResourceHandle>& resourceHandles
-                                                )
+                                 const std::vector<OCResourceHandle>& resourceHandles)
         {
             return OCPlatform_impl::Instance().unbindResources(collectionHandle, resourceHandles);
         }
 
         OCStackResult bindResource(const OCResourceHandle collectionHandle,
-                                                const OCResourceHandle resourceHandle)
+                                 const OCResourceHandle resourceHandle)
         {
             return OCPlatform_impl::Instance().bindResource(collectionHandle, resourceHandle);
         }
 
         OCStackResult bindResources(const OCResourceHandle collectionHandle,
-                                                const std::vector<OCResourceHandle>& resourceHandles
-                                                )
+                                 const std::vector<OCResourceHandle>& resourceHandles
+                                 )
         {
             return OCPlatform_impl::Instance().bindResources(collectionHandle, resourceHandles);
         }
 
         OCStackResult bindTypeToResource(const OCResourceHandle& resourceHandle,
-                                                const std::string& resourceTypeName)
+                                 const std::string& resourceTypeName)
         {
             return OCPlatform_impl::Instance().bindTypeToResource(resourceHandle,resourceTypeName);
         }
 
         OCStackResult bindInterfaceToResource(const OCResourceHandle& resourceHandle,
-                                                const std::string& resourceInterfaceName)
+                                 const std::string& resourceInterfaceName)
         {
             return OCPlatform_impl::Instance().bindInterfaceToResource(resourceHandle,
-                                                resourceInterfaceName);
+                                                             resourceInterfaceName);
         }
 
         OCStackResult startPresence(const unsigned int announceDurationSeconds)
@@ -244,22 +243,22 @@ namespace OC
         }
 
         OCStackResult subscribePresence(OCPresenceHandle& presenceHandle,
-                                                const std::string& host,
-                                                OCConnectivityType connectivityType,
-                                                SubscribeCallback presenceHandler)
+                                     const std::string& host,
+                                     OCConnectivityType connectivityType,
+                                     SubscribeCallback presenceHandler)
         {
             return OCPlatform_impl::Instance().subscribePresence(presenceHandle, host,
-                                                connectivityType, presenceHandler);
+                                                             connectivityType, presenceHandler);
         }
 
         OCStackResult subscribePresence(OCPresenceHandle& presenceHandle,
-                                                const std::string& host,
-                                                const std::string& resourceType,
-                                                OCConnectivityType connectivityType,
-                                                SubscribeCallback presenceHandler)
+                                     const std::string& host,
+                                     const std::string& resourceType,
+                                     OCConnectivityType connectivityType,
+                                     SubscribeCallback presenceHandler)
         {
             return OCPlatform_impl::Instance().subscribePresence(presenceHandle, host,
-                                                resourceType, connectivityType, presenceHandler);
+                                             resourceType, connectivityType, presenceHandler);
         }
 
         OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle)
@@ -271,6 +270,27 @@ namespace OC
         {
             return OCPlatform_impl::Instance().sendResponse(pResponse);
         }
+
+        OCStackResult findDirectPairingDevices(unsigned short waittime,
+                                         GetDirectPairedCallback directPairingHandler)
+        {
+            return OCPlatform_impl::Instance().findDirectPairingDevices(waittime,
+                                         directPairingHandler);
+        }
+
+        OCStackResult getDirectPairedDevices(GetDirectPairedCallback directPairingHandler)
+        {
+            return OCPlatform_impl::Instance().getDirectPairedDevices(directPairingHandler);
+        }
+
+        OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel,
+                                 const std::string& pinNumber,
+                                 DirectPairingCallback resultCallback)
+        {
+            return OCPlatform_impl::Instance().doDirectPairing(peer, pmSel,
+                                             pinNumber, resultCallback);
+        }
+
     } // namespace OCPlatform
 } //namespace OC
 
index 059944c..03fa1d9 100644 (file)
@@ -387,5 +387,31 @@ namespace OC
     {
         return m_csdkLock;
     }
+
+    OCStackResult OCPlatform_impl::findDirectPairingDevices(unsigned short waittime,
+                             GetDirectPairedCallback directPairingHandler)
+    {
+        return checked_guard(m_client, &IClientWrapper::FindDirectPairingDevices,
+                             waittime, directPairingHandler);
+
+    }
+
+    OCStackResult OCPlatform_impl::getDirectPairedDevices(
+                             GetDirectPairedCallback directPairingHandler)
+    {
+
+        return checked_guard(m_client, &IClientWrapper::GetDirectPairedDevices,
+                             directPairingHandler);
+    }
+
+    OCStackResult OCPlatform_impl::doDirectPairing(std::shared_ptr<OCDirectPairing> peer,
+                             OCPrm_t pmSel,
+                             const std::string& pinNumber,
+                             DirectPairingCallback resultCallback)
+    {
+        return checked_guard(m_client, &IClientWrapper::DoDirectPairing,
+                             peer, pmSel, pinNumber, resultCallback);
+    }
+
 } //namespace OC
 
index a3c8ec8..9ea55f6 100644 (file)
@@ -122,7 +122,7 @@ void OCResource::setHost(const std::string& host)
     else if(host.compare(0, sizeof(COAPS) - 1, COAPS) == 0)
     {
         prefix_len = sizeof(COAPS) - 1;
-        m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags & OC_SECURE);
+        m_devAddr.flags = static_cast<OCTransportFlags>(m_devAddr.flags | OC_SECURE);
     }
     else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0)
     {
index f1106a1..acfe0e1 100644 (file)
@@ -80,7 +80,8 @@ oclib_src = [
                'InProcServerWrapper.cpp',
                'InProcClientWrapper.cpp',
                'OCResourceRequest.cpp',
-               'CAManager.cpp'
+               'CAManager.cpp',
+               'OCDirectPairing.cpp'
        ]
 
 oclib = oclib_env.SharedLibrary('oc', oclib_src)
@@ -115,6 +116,7 @@ oclib_env.UserInstallTargetHeader(header_dir + 'OCResourceResponse.h', 'resource
 oclib_env.UserInstallTargetHeader(header_dir + 'OCUtilities.h', 'resource', 'OCUtilities.h')
 
 oclib_env.UserInstallTargetHeader(header_dir + 'CAManager.h', 'resource', 'CAManager.h')
+oclib_env.UserInstallTargetHeader(header_dir + 'OCDirectPairing.h', 'resource', 'OCDirectPairing.h')
 
 # Add Provisioning library
 if target_os in ['linux', 'android', 'tizen'] and env.get('SECURED') == '1':
index fc59f96..93f62e4 100644 (file)
@@ -62,6 +62,14 @@ namespace OCPlatformTest
     {
     }
 
+    void directPairHandler(std::shared_ptr<OCDirectPairing> /*dev*/, OCStackResult /*res*/)
+    {
+    }
+
+    void pairedHandler(const PairedDevices& /*list*/)
+    {
+    }
+
     //Helper methods
     void DeleteStringLL(OCStringLL* ll)
     {
@@ -818,4 +826,46 @@ namespace OCPlatformTest
                 OC_MULTICAST_IP, CT_DEFAULT, &presenceHandler));
         EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle));
     }
+
+    TEST(FindDirectPairingTest, FindDirectPairingNullCallback)
+    {
+        EXPECT_ANY_THROW(OCPlatform::findDirectPairingDevices(1, nullptr));
+    }
+
+    TEST(FindDirectPairingTest, FindDirectPairingZeroTimeout)
+    {
+        EXPECT_ANY_THROW(OCPlatform::findDirectPairingDevices(0, &pairedHandler));
+    }
+
+    TEST(GetDirectPairedTest, GetDirectPairedNullCallback)
+    {
+        EXPECT_ANY_THROW(OCPlatform::getDirectPairedDevices(nullptr));
+    }
+
+    TEST(DoDirectPairingTest, DoDirectPairingNullCallback)
+    {
+        OCDPDev_t peer;
+        OCPrm_t pmSel = DP_PRE_CONFIGURED;
+        std::string pin("");
+        std::shared_ptr<OCDirectPairing> s_dp(new OCDirectPairing(&peer));
+        EXPECT_ANY_THROW(OCPlatform::doDirectPairing(s_dp, pmSel, pin, nullptr));
+    }
+
+    TEST(DoDirectPairingTest, DoDirectPairingNullPeer)
+    {
+        OCDPDev_t peer;
+        OCPrm_t pmSel = DP_PRE_CONFIGURED;
+        std::string pin("");
+        std::shared_ptr<OCDirectPairing> s_dp(new OCDirectPairing(&peer));
+        EXPECT_ANY_THROW(OCPlatform::doDirectPairing(nullptr, pmSel, pin, &directPairHandler));
+    }
+
+    TEST(DoDirectPairingTest, DoDirectPairingNullPeerNullCallback)
+    {
+        OCDPDev_t peer;
+        OCPrm_t pmSel = DP_PRE_CONFIGURED;
+        std::string pin("");
+        std::shared_ptr<OCDirectPairing> s_dp(new OCDirectPairing(&peer));
+        EXPECT_ANY_THROW(OCPlatform::doDirectPairing(nullptr, pmSel, pin, nullptr));
+    }
 }