Device Discovery - C & C++ SDK changes
authoromkar <omkar.m.hegde@intel.com>
Thu, 20 Nov 2014 18:55:35 +0000 (10:55 -0800)
committeromkar <omkar.m.hegde@intel.com>
Thu, 18 Dec 2014 23:38:42 +0000 (15:38 -0800)
Adding API for setting device information.
Currently supports filtering of device information based on device id and
device name only.
Updated C and C++ sample applications

Change-Id: Ie2fbfac8c9444560633b9716e777d4697a146f66
Signed-off-by: omkar <omkar.m.hegde@intel.com>
27 files changed:
resource/csdk/occoap/src/occoap.c
resource/csdk/stack/include/internal/ocresourcehandler.h
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/ocstackconfig.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.h
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocstack.c
resource/examples/SConscript
resource/examples/devicediscoveryclient.cpp [new file with mode: 0644]
resource/examples/devicediscoveryserver.cpp [new file with mode: 0644]
resource/examples/makefile
resource/include/IClientWrapper.h
resource/include/IServerWrapper.h
resource/include/InProcClientWrapper.h
resource/include/InProcServerWrapper.h
resource/include/OCApi.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OutOfProcClientWrapper.h
resource/include/OutOfProcServerWrapper.h
resource/src/InProcClientWrapper.cpp
resource/src/InProcServerWrapper.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp

index 5c2e7ed..78bce42 100644 (file)
@@ -228,7 +228,8 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
     if(requestResult == OC_STACK_VIRTUAL_DO_NOT_HANDLE ||
             requestResult == OC_STACK_OK ||
             requestResult == OC_STACK_RESOURCE_CREATED ||
-            requestResult == OC_STACK_RESOURCE_DELETED)
+            requestResult == OC_STACK_RESOURCE_DELETED ||
+            requestResult == OC_STACK_INVALID_DEVICE_INFO)
     {
         goto exit;
     }
index 505a598..f56769c 100755 (executable)
@@ -31,6 +31,8 @@
 #define OC_RSRVD_RESOURCE_TYPE          "rt"
 #define OC_RSRVD_RESOURCE_TYPE_PRESENCE "core.presence"
 #define OC_RSRVD_INTERFACE              "if"
+#define OC_RSRVD_DEVICE_ID              "di"
+#define OC_RSRVD_DEVICE_NAME            "dn"
 #define OC_RSRVD_INTERFACE_DEFAULT      "oc.mi.def"
 #define OC_RSRVD_INTERFACE_LL           "oc.mi.ll"
 #define OC_RSRVD_INTERFACE_BATCH        "oc.mi.b"
@@ -53,7 +55,9 @@
 typedef enum {
     STACK_RES_DISCOVERY_NOFILTER = 0,
     STACK_RES_DISCOVERY_IF_FILTER,
-    STACK_RES_DISCOVERY_RT_FILTER
+    STACK_RES_DISCOVERY_RT_FILTER,
+    STACK_DEVICE_DISCOVERY_DI_FILTER,
+    STACK_DEVICE_DISCOVERY_DN_FILTER
 } StackQueryTypes;
 
 typedef enum {
@@ -80,6 +84,10 @@ OCStackResult DetermineResourceHandling (OCServerRequest *request,
 OCStackResult
 ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerRequest *request);
 
+OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo);
+
+void DeleteDeviceInfo();
+
 OCStackResult
 BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filterOn,
                         char *filterValue, char * out, uint16_t *remaining);
index 085f497..ab348f9 100644 (file)
@@ -170,6 +170,7 @@ typedef enum {
     OC_STACK_MALFORMED_RESPONSE,        /* the remote reply contained malformed data */
     OC_STACK_PERSISTENT_BUFFER_REQUIRED,
     OC_STACK_INVALID_REQUEST_HANDLE,
+    OC_STACK_INVALID_DEVICE_INFO,
     OC_STACK_ERROR
     /* Error status code - END HERE */
 } OCStackResult;
@@ -276,6 +277,26 @@ typedef struct {
     OCHeaderOption rcvdVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS];
 }OCClientResponse;
 
+/**
+ * Following structure describes the device properties. All non-Null properties will be included
+ * in a device discovery request.
+ */
+typedef struct
+{
+    char *deviceName;
+    char *hostName;
+    char *deviceUUID;
+    char *contentType;
+    char *version;
+    char *manufacturerName;
+    char *manufacturerUrl;
+    char *modelNumber;
+    char *dateOfManufacture;
+    char *platformVersion;
+    char *firmwareVersion;
+    char *supportUrl;
+} OCDeviceInfo;
+
 typedef struct
 {
     // Request handle is passed to server via the entity handler for each incoming request.
@@ -490,6 +511,20 @@ OCStackResult OCStopPresence();
 OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler);
 
 /**
+ * Set device information.
+ *
+ * @param deviceInfo - Structure passed by the server application containing
+ *                     the device information.
+ *
+ *
+ * @return
+ *     OC_STACK_OK              - no errors
+ *     OC_STACK_INVALID_PARAM   - invalid paramerter
+ *     OC_STACK_ERROR           - stack process error
+ */
+OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo);
+
+/**
  * Create a resource.
  *
  * @param handle - pointer to handle to newly created resource.  Set by ocstack.  Used to refer to resource
index 650949c..9e14bd3 100644 (file)
 #define MAX_QUERY_LENGTH (64)
 
 /**
+ * Maximum length of the Manufacturer name supported by the server
+ * for manufacturer name
+ */
+#define MAX_MANUFACTURER_NAME_LENGTH (16)
+
+/**
+ * Maximum length of the URL to the Manufacturer details supported by
+ * the server.
+ */
+#define MAX_MANUFACTURER_URL_LENGTH (32)
+
+/**
  * Maximum number of resources which can be contained inside collection
  * resource.
  */
index 9f70f52..ed5f054 100644 (file)
@@ -32,6 +32,8 @@
 static int UNICAST_DISCOVERY = 0;
 static int TEST_CASE = 0;
 static const char * TEST_APP_UNICAST_DISCOVERY_QUERY = "coap://0.0.0.0:5683/oc/core";
+static const char * TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY = "coap://0.0.0.0:5683/oc/core/d";
+static const char * TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY = "coap://224.0.1.187:5683/oc/core/d";
 static std::string putPayload = "{\"state\":\"on\",\"power\":5}";
 static std::string coapServerIP = "255.255.255.255";
 static std::string coapServerPort = "5683";
@@ -82,6 +84,7 @@ static void PrintUsage()
 
     OC_LOG(INFO, TAG, "-t 14 :  Discover Resources and Initiate Nonconfirmable Observe Requests then cancel immediately");
     OC_LOG(INFO, TAG, "-t 15 :  Discover Resources and Initiate Nonconfirmable Get Request and add  vendor specific header options");
+    OC_LOG(INFO, TAG, "-t 16  :  Discover Devices");
 }
 
 OCStackResult InvokeOCDoResource(std::ostringstream &query,
@@ -330,6 +333,9 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
             case TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS:
                 InitGetRequest(OC_LOW_QOS, 1);
                 break;
+            case TEST_DISCOVER_DEV_REQ:
+                InitDeviceDiscovery();
+                break;
             default:
                 PrintUsage();
                 break;
@@ -339,6 +345,25 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle,
     return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION ;
 
 }
+
+OCStackApplicationResult DeviceDiscoveryReqCB (void* ctx, OCDoHandle handle,
+        OCClientResponse * clientResponse)
+{
+    if (ctx == (void*) DEFAULT_CONTEXT_VALUE)
+    {
+        OC_LOG(INFO, TAG, "Callback Context for Device DISCOVER query recvd successfully");
+    }
+
+    if(clientResponse)
+    {
+        //OC_LOG truncates the response as it is too long.
+        fprintf(stderr, "Discovery response: \n %s\n", clientResponse->resJSONPayload);
+        fflush(stderr);
+    }
+
+    return (UNICAST_DISCOVERY) ? OC_STACK_DELETE_TRANSACTION : OC_STACK_KEEP_TRANSACTION;
+}
+
 #ifdef WITH_PRESENCE
 int InitPresence()
 {
@@ -495,6 +520,38 @@ int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptio
     }
 }
 
+int InitDeviceDiscovery()
+{
+    OCStackResult ret;
+    OCCallbackData cbData;
+    OCDoHandle handle;
+    char szQueryUri[64] = { 0 };
+
+    cbData.cb = DeviceDiscoveryReqCB;
+    cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
+    cbData.cd = NULL;
+
+    if(UNICAST_DISCOVERY)
+    {
+        strncpy(szQueryUri, TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY,
+                        (strlen(TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY) + 1));
+    }
+    else
+    {
+        strncpy(szQueryUri, TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY,
+                (strlen(TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY) + 1));
+    }
+
+    ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, OC_LOW_QOS, &cbData, NULL, 0);
+
+    if (ret != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, "OCStack device error");
+    }
+
+    return ret;
+}
+
 int InitDiscovery()
 {
     OCStackResult ret;
index cb59cb0..f106f7b 100644 (file)
@@ -58,6 +58,7 @@ typedef enum {
 #endif
     TEST_OBS_REQ_NON_CANCEL_IMM,
     TEST_GET_REQ_NON_WITH_VENDOR_HEADER_OPTIONS,
+    TEST_DISCOVER_DEV_REQ,
     MAX_TESTS
 } CLIENT_TEST;
 
@@ -91,6 +92,7 @@ int InitGetRequest(OCQualityOfService qos, uint8_t withVendorSpecificHeaderOptio
 int InitPostRequest(OCQualityOfService qos);
 int InitDeleteRequest(OCQualityOfService qos);
 int InitGetRequest(OCQualityOfService qos);
+int InitDeviceDiscovery();
 int InitDiscovery();
 
 /* Function to retrieve ip address, port no. of the server
index 1bed2bf..0311507 100644 (file)
@@ -61,6 +61,20 @@ const char responsePayloadDeleteResourceNotSupported[] =
 
 
 char *gResourceUri= (char *)"/a/light";
+const char *contentType = "myContentType";
+const char *dateOfManufacture = "myDateOfManufacture";
+const char *deviceName = "myDeviceName";
+const char *deviceUUID = "myDeviceUUID";
+const char *firmwareVersion = "myFirmwareVersion";
+const char *hostName = "myHostName";
+const char *manufacturerName = "myManufacturerNa";
+const char *manufacturerUrl = "myManufacturerUrl";
+const char *modelNumber = "myModelNumber";
+const char *platformVersion = "myPlatformVersion";
+const char *supportUrl = "mySupportUrl";
+const char *version = "myVersion";
+
+OCDeviceInfo deviceInfo;
 
 static uint16_t OC_WELL_KNOWN_PORT = 5683;
 
@@ -729,6 +743,24 @@ int main(int argc, char* argv[])
 
     OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandlerCb);
 
+    OCStackResult deviceResult = SetDeviceInfo(contentType, dateOfManufacture, deviceName,
+            deviceUUID, firmwareVersion, hostName, manufacturerName,
+            manufacturerUrl, modelNumber, platformVersion, supportUrl, version);
+
+    if (deviceResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device Registration failed!");
+        exit (EXIT_FAILURE);
+    }
+
+    deviceResult = OCSetDeviceInfo(deviceInfo);
+
+    if (deviceResult != OC_STACK_OK)
+    {
+        OC_LOG(INFO, TAG, "Device Registration failed!");
+        exit (EXIT_FAILURE);
+    }
+
     /*
      * Declare and create the example resource: Light
      */
@@ -747,6 +779,7 @@ int main(int argc, char* argv[])
 
     // Break from loop with Ctrl-C
     OC_LOG(INFO, TAG, "Entering ocserver main loop...");
+    DeleteDeviceInfo();
     signal(SIGINT, handleSigInt);
     while (!gQuitFlag) {
         if (OCProcess() != OC_STACK_OK) {
@@ -792,3 +825,126 @@ int createLightResource (char *uri, LightResource *lightResource)
 
     return 0;
 }
+
+void DeleteDeviceInfo()
+{
+    free(deviceInfo.contentType);
+    free(deviceInfo.dateOfManufacture);
+    free(deviceInfo.deviceName);
+    free(deviceInfo.deviceUUID);
+    free(deviceInfo.firmwareVersion);
+    free(deviceInfo.hostName);
+    free(deviceInfo.manufacturerName);
+    free(deviceInfo.manufacturerUrl);
+    free(deviceInfo.modelNumber);
+    free(deviceInfo.platformVersion);
+    free(deviceInfo.supportUrl);
+    free(deviceInfo.version);
+}
+
+bool DuplicateString(char** targetString, const char* sourceString)
+{
+    if(!sourceString)
+    {
+        return false;
+    }
+    else
+    {
+        *targetString = (char *) malloc(strlen(sourceString) + 1);
+
+        if(targetString)
+        {
+            strncpy(*targetString, sourceString, (strlen(sourceString) + 1));
+            return true;
+        }
+    }
+    return false;
+}
+
+OCStackResult SetDeviceInfo(const char *contentType, const char *dateOfManufacture,
+        const char *deviceName, const char *deviceUUID, const char *firmwareVersion,
+        const char *hostName, const char *manufacturerName, const char *manufacturerUrl,
+        const char *modelNumber, const char *platformVersion, const char *supportUrl,
+        const char *version)
+{
+
+    bool success = true;
+
+    if(manufacturerName != NULL && (strlen(manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH))
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if(manufacturerUrl != NULL && (strlen(manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH))
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if(!DuplicateString(&deviceInfo.contentType, contentType))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.dateOfManufacture, dateOfManufacture))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.deviceName, deviceName))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.deviceUUID, deviceUUID))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.firmwareVersion, firmwareVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.hostName, hostName))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.manufacturerName, manufacturerName))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.manufacturerUrl, manufacturerUrl))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.modelNumber, modelNumber))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.platformVersion, platformVersion))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.supportUrl, supportUrl))
+    {
+        success = false;
+    }
+
+    if(!DuplicateString(&deviceInfo.version, version))
+    {
+        success = false;
+    }
+
+    if(success)
+    {
+        return OC_STACK_OK;
+    }
+
+    DeleteDeviceInfo();
+    return OC_STACK_ERROR;
+}
index f5e45e5..81a9507 100644 (file)
@@ -91,6 +91,15 @@ OCEntityHandlerResult ProcessNonExistingResourceRequest (OCEntityHandlerRequest
 void ProcessObserveRegister (OCEntityHandlerRequest *ehRequest);
 void ProcessObserveDeregister (OCEntityHandlerRequest *ehRequest);
 
+void DeleteDeviceInfo();
+
+OCStackResult SetDeviceInfo(const char *contentType, const char *dateOfManufacture,
+                const char *deviceName, const char *deviceUUID, const char *firmwareVersion,
+                const char *hostName, const char *manufacturerName, const char *manufacturerUrl,
+                const char *modelNumber, const char *platformVersion, const char *supportUrl,
+                const char *version);
+
+
 //-----------------------------------------------------------------------------
 // Callback functions
 //-----------------------------------------------------------------------------
index a2a1c4e..f2267d1 100644 (file)
@@ -40,6 +40,7 @@
              TAG, PCF(#arg " is NULL")); return (retVal); } }
 
 extern OCResource *headResource;
+static cJSON *savedDeviceInfo = NULL;
 
 static const char * VIRTUAL_RSRCS[] = {
        "/oc/core",
@@ -71,7 +72,8 @@ static OCStackResult ValidateUrlQuery (unsigned char *url, unsigned char *query,
     if (!url)
         return OC_STACK_INVALID_URI;
 
-    if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0) {
+    if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
+                strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0) {
         *filterOn = STACK_RES_DISCOVERY_NOFILTER;
         if (query && *query) {
             char* strTokPtr;
@@ -85,6 +87,12 @@ static OCStackResult ValidateUrlQuery (unsigned char *url, unsigned char *query,
             } else if (strcmp (filterParam, OC_RSRVD_RESOURCE_TYPE) == 0) {
                 // Resource discovery with resource type filter
                 *filterOn = STACK_RES_DISCOVERY_RT_FILTER;
+            } else if (strcmp (filterParam, OC_RSRVD_DEVICE_ID) == 0) {
+                //Device ID filter
+                *filterOn = STACK_DEVICE_DISCOVERY_DI_FILTER;
+            } else if (strcmp (filterParam, OC_RSRVD_DEVICE_NAME) == 0) {
+                //Device Name filter
+                *filterOn = STACK_DEVICE_DISCOVERY_DN_FILTER;
             } else {
                 // Other filter types not supported
                 return OC_STACK_INVALID_QUERY;
@@ -205,6 +213,85 @@ OCStackResult BuildVirtualResourceResponse(OCResource *resourcePtr, uint8_t filt
     return ret;
 }
 
+OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filterValue,
+                                                    char *out, uint16_t *remaining)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+
+    if (savedDeviceInfo != NULL)
+    {
+        char *jsonStr = NULL;
+        uint16_t jsonLen = 0;
+        cJSON *repObj = cJSON_GetObjectItem(savedDeviceInfo, "rep");
+
+        OC_LOG(INFO, TAG, PCF("Entering BuildVirtualResourceResponseForDevice"));
+
+        if (filterOn == STACK_DEVICE_DISCOVERY_DI_FILTER)
+        {
+            if((cJSON_GetObjectItem(repObj,"di") != NULL) &&
+                    strcmp(cJSON_GetObjectItem(repObj,"di")->valuestring, filterValue) == 0)
+            {
+                ret = OC_STACK_OK;
+            }
+        }
+        else if (filterOn == STACK_DEVICE_DISCOVERY_DN_FILTER)
+        {
+            if((cJSON_GetObjectItem(repObj,"dn") != NULL) &&
+                    strcmp(cJSON_GetObjectItem(repObj,"dn")->valuestring, filterValue) == 0)
+            {
+                ret = OC_STACK_OK;
+            }
+        }
+        else if (filterOn == STACK_RES_DISCOVERY_NOFILTER)
+        {
+            ret = OC_STACK_OK;
+        }
+        else
+        {
+            ret = OC_STACK_INVALID_QUERY;
+        }
+
+        if (ret == OC_STACK_OK)
+        {
+            jsonStr = cJSON_PrintUnformatted (savedDeviceInfo);
+
+            if(jsonStr)
+            {
+                jsonLen = strlen(jsonStr);
+
+                if (jsonLen < *remaining)
+                {
+                    strncpy(out, jsonStr, (jsonLen + 1));
+                    *remaining = *remaining - jsonLen;
+                    ret = OC_STACK_OK;
+                }
+                else
+                {
+                    ret = OC_STACK_ERROR;
+                }
+
+                free(jsonStr);
+            }
+            else
+            {
+                ret = OC_STACK_ERROR;
+            }
+        }
+        else
+        {
+            ret = OC_STACK_INVALID_DEVICE_INFO;
+        }
+    }
+    else
+    {
+        //error so that stack won't respond with empty payload
+        ret = OC_STACK_INVALID_DEVICE_INFO;
+    }
+
+    OC_LOG(INFO, TAG, PCF("Exiting BuildVirtualResourceResponseForDevice"));
+    return ret;
+}
+
 TODO ("Does it make sense to make this method as inline")
 const char * GetVirtualResourceUri( OCVirtualResources resource)
 {
@@ -429,6 +516,33 @@ HandleVirtualResource (OCServerRequest *request, OCResource* resource)
                 result = OCDoResponse(&response);
             }
         }
+        else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
+        {
+            remaining = MAX_RESPONSE_LENGTH;
+            ptr = discoveryResBuf;
+
+            result = BuildVirtualResourceResponseForDevice(filterOn, filterValue,
+                    (char*)ptr, &remaining);
+
+            if(result == OC_STACK_OK)
+            {
+                ptr += strlen((char*)ptr);
+            }
+
+            if(remaining < MAX_RESPONSE_LENGTH)
+            {
+                OCEntityHandlerResponse response = {0};
+
+                response.ehResult = OC_EH_OK;
+                response.payload = discoveryResBuf;
+                response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
+                response.persistentBufferFlag = 0;
+                response.requestHandle = (OCRequestHandle) request;
+                response.resourceHandle = (OCResourceHandle) resource;
+
+                result = OCDoResponse(&response);
+            }
+        }
         #ifdef WITH_PRESENCE
         else
         {
@@ -644,4 +758,109 @@ ProcessRequest(ResourceHandling resHandling, OCResource *resource, OCServerReque
     return ret;
 }
 
+void DeleteDeviceInfo()
+{
+    if(savedDeviceInfo)
+    {
+        cJSON_Delete(savedDeviceInfo);
+    }
+}
+
+OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo)
+{
+    DeleteDeviceInfo();
+
+    savedDeviceInfo = cJSON_CreateObject();
+    cJSON *repObj = NULL;
+
+    cJSON_AddItemToObject (savedDeviceInfo, OC_RSRVD_HREF,
+            cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
+
+    cJSON_AddItemToObject (savedDeviceInfo, "rep", repObj = cJSON_CreateObject());
+
+    if (deviceInfo.contentType)
+    {
+        cJSON_AddItemToObject (repObj, "ct",
+                cJSON_CreateString(deviceInfo.contentType));
+    }
+
+    if (deviceInfo.dateOfManufacture)
+    {
+        cJSON_AddItemToObject (repObj, "mndt",
+                cJSON_CreateString(deviceInfo.dateOfManufacture));
+    }
+
+    if (deviceInfo.deviceName)
+    {
+        cJSON_AddItemToObject (repObj, "dn",
+                cJSON_CreateString(deviceInfo.deviceName));
+    }
+
+    if (deviceInfo.deviceUUID)
+    {
+        cJSON_AddItemToObject (repObj, "di",
+                cJSON_CreateString(deviceInfo.deviceUUID));
+    }
+
+    if (deviceInfo.firmwareVersion)
+    {
+        cJSON_AddItemToObject (repObj, "mnfv",
+                cJSON_CreateString(deviceInfo.firmwareVersion));
+    }
+
+    if (deviceInfo.hostName)
+    {
+        cJSON_AddItemToObject (repObj, "hn", cJSON_CreateString(deviceInfo.hostName));
+    }
+
+    if (deviceInfo.manufacturerName)
+    {
+        if(strlen(deviceInfo.manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        cJSON_AddItemToObject (repObj, "mnmn",
+                cJSON_CreateString(deviceInfo.manufacturerName));
+    }
+
+    if (deviceInfo.manufacturerUrl)
+    {
+        if(strlen(deviceInfo.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
+        {
+            DeleteDeviceInfo();
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        cJSON_AddItemToObject (repObj, "mnml",
+                cJSON_CreateString(deviceInfo.manufacturerUrl));
+    }
+
+    if (deviceInfo.modelNumber)
+    {
+        cJSON_AddItemToObject (repObj, "mnmo",
+                cJSON_CreateString(deviceInfo.modelNumber));
+    }
+
+    if (deviceInfo.platformVersion)
+    {
+        cJSON_AddItemToObject (repObj, "mnpv",
+                cJSON_CreateString(deviceInfo.platformVersion));
+    }
+
+    if (deviceInfo.supportUrl)
+    {
+        cJSON_AddItemToObject (repObj, "mnsl",
+                cJSON_CreateString(deviceInfo.supportUrl));
+    }
+
+    if (deviceInfo.version)
+    {
+        cJSON_AddItemToObject (repObj, "icv",
+                cJSON_CreateString(deviceInfo.version));
+    }
+
+    return OC_STACK_OK;
+}
 
index fd4c754..b2aec91 100644 (file)
@@ -457,6 +457,7 @@ OCStackResult OCStop()
 
     // Free memory dynamically allocated for resources
     deleteAllResources();
+    DeleteDeviceInfo();
 
     // Make call to OCCoAP layer
     if (OCStopCoAP() == OC_STACK_OK)
@@ -913,6 +914,18 @@ OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandle
     return OC_STACK_OK;
 }
 
+OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
+{
+    OC_LOG(INFO, TAG, PCF("Entering OCSetDeviceInfo"));
+
+    if(myStackMode == OC_CLIENT)
+    {
+        return OC_STACK_ERROR;
+    }
+
+    return SaveDeviceInfo(deviceInfo);
+}
+
 /**
  * Create a resource
  *
index 12a7dcc..4a12d01 100644 (file)
@@ -60,11 +60,13 @@ roomserver = examples_env.Program('roomserver', 'roomserver.cpp')
 roomclient = examples_env.Program('roomclient', 'roomclient.cpp')
 garageserver = examples_env.Program('garageserver', 'garageserver.cpp')
 garageclient = examples_env.Program('garageclient', 'garageclient.cpp')
+devicediscoveryserver = examples_env.Program('devicediscoveryserver', 'devicediscoveryserver.cpp')
+devicediscoveryclient = examples_env.Program('devicediscoveryclient', 'devicediscoveryclient.cpp')
 
 Alias("examples", [simpleserver, simpleserverHQ, simpleclient, simpleclientHQ,
                fridgeserver, fridgeclient, presenceserver, presenceclient,
                simpleclientserver, roomserver, roomclient, garageserver,
-               garageclient])
+               garageclient, devicediscoveryserver, devicediscoveryclient])
 env.AppendTarget('examples')
 
 #ios doesn't allow run application from terminal, so won't build these examples
diff --git a/resource/examples/devicediscoveryclient.cpp b/resource/examples/devicediscoveryclient.cpp
new file mode 100644 (file)
index 0000000..f08a8c7
--- /dev/null
@@ -0,0 +1,147 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+///This sample demonstrates the device discovery feature
+///The client queries for the device related information
+///stored by the server.
+///
+
+#include <mutex>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+//Callback after device information is received
+void receivedDeviceInfo(const OCRepresentation& rep)
+{
+    std::cout << "\nDevice Information received ---->\n";
+
+    std::string contentType;
+    std::string dateOfManufacture;
+    std::string deviceName;
+    std::string deviceUUID;
+    std::string firmwareVersion;
+    std::string hostName;
+    std::string manufacturerName;
+    std::string manufacturerUrl;
+    std::string modelNumber;
+    std::string platformVersion;
+    std::string supportUrl;
+    std::string version;
+
+    if(rep.getValue("ct", contentType))
+    {
+        std::cout << "Content Type: " << contentType << std::endl;
+    }
+
+    if(rep.getValue("mndt", dateOfManufacture))
+    {
+        std::cout << "Date of manufacture: " << dateOfManufacture << std::endl;
+    }
+
+    if(rep.getValue("dn", deviceName))
+    {
+        std::cout << "Device Name: " << deviceName << std::endl;
+    }
+
+    if(rep.getValue("di", deviceUUID))
+    {
+        std::cout << "Device UUID: " << deviceUUID << std::endl;
+    }
+
+    if(rep.getValue("mnfv", firmwareVersion))
+    {
+        std::cout << "Firmware Version: " << firmwareVersion << std::endl;
+    }
+
+    if(rep.getValue("hn", hostName))
+    {
+        std::cout << "Host Name: " << hostName << std::endl;
+    }
+
+    if(rep.getValue("mnmn", manufacturerName))
+    {
+        std::cout << "Manufacturer Name: " << manufacturerName << std::endl;
+    }
+
+    if(rep.getValue("mnml", manufacturerUrl))
+    {
+        std::cout << "Manufacturer Url: " << manufacturerUrl << std::endl;
+    }
+
+    if(rep.getValue("mnmo", modelNumber))
+    {
+        std::cout << "Model No. : " << modelNumber << std::endl;
+    }
+
+    if(rep.getValue("mnpv", platformVersion))
+    {
+        std::cout << "Platform Version: " << platformVersion << std::endl;
+    }
+
+    if(rep.getValue("mnsl", supportUrl))
+    {
+        std::cout << "Support URL: " << supportUrl << std::endl;
+    }
+
+    if(rep.getValue("icv", version))
+    {
+        std::cout << "Version: " << version << std::endl;
+    }
+}
+
+int main() {
+
+    // Create PlatformConfig object
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Client,
+        "0.0.0.0",
+        0,
+        OC::QualityOfService::LowQos
+    };
+
+    OCPlatform::Configure(cfg);
+    try
+    {
+        OCPlatform::getDeviceInfo("", "coap://224.0.1.187/oc/core/d", &receivedDeviceInfo);
+        std::cout<< "Querying for device information... " <<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)
+    {
+        //log(e.what());
+    }
+
+    return 0;
+}
+
diff --git a/resource/examples/devicediscoveryserver.cpp b/resource/examples/devicediscoveryserver.cpp
new file mode 100644 (file)
index 0000000..4a7494d
--- /dev/null
@@ -0,0 +1,170 @@
+//******************************************************************
+//
+// Copyright 2014 Intel Mobile Communications GmbH 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+///This sample demonstrates the device discovery feature
+///The server sets the device related info. which can
+///be later retrieved by a client.
+///
+
+#include <mutex>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+using namespace OC;
+
+//Set of strings for each of deviceInfo fields
+std::string contentType = "myContentType";
+std::string dateOfManufacture = "myDateOfManufacture";
+std::string deviceName = "myDeviceName";
+std::string deviceUUID = "myDeviceUUID";
+std::string firmwareVersion = "myFirmwareVersion";
+std::string hostName = "myHostName";
+std::string manufacturerName = "myManufacturerNa";
+std::string manufacturerUrl = "myManufacturerUrl";
+std::string modelNumber = "myModelNumber";
+std::string platformVersion = "myPlatformVersion";
+std::string supportUrl = "mySupportUrl";
+std::string version = "myVersion";
+
+//OCDeviceInfo Contains all the device info to be stored
+OCDeviceInfo deviceInfo;
+
+void DeleteDeviceInfo()
+{
+    delete deviceInfo.contentType;
+    delete deviceInfo.dateOfManufacture;
+    delete deviceInfo.deviceName;
+    delete deviceInfo.deviceUUID;
+    delete deviceInfo.firmwareVersion;
+    delete deviceInfo.hostName;
+    delete deviceInfo.manufacturerName;
+    delete deviceInfo.manufacturerUrl;
+    delete deviceInfo.modelNumber;
+    delete deviceInfo.platformVersion;
+    delete deviceInfo.supportUrl;
+    delete deviceInfo.version;
+}
+
+void DuplicateString(char ** targetString, std::string sourceString)
+{
+    *targetString = new char[sourceString.length() + 1];
+    strncpy(*targetString, sourceString.c_str(), (sourceString.length() + 1));
+}
+
+OCStackResult SetDeviceInfo(std::string contentType, std::string dateOfManufacture,
+                std::string deviceName, std::string deviceUUID, std::string firmwareVersion,
+                std::string hostName, std::string manufacturerName, std::string manufacturerUrl,
+                std::string modelNumber, std::string platformVersion, std::string supportUrl,
+                std::string version)
+{
+    if(manufacturerName.length() > MAX_MANUFACTURER_NAME_LENGTH)
+    {
+        return OC_STACK_INVALID_PARAM;
+
+    }
+
+    if(manufacturerUrl.length() > MAX_MANUFACTURER_URL_LENGTH)
+    {
+        return OC_STACK_INVALID_PARAM;
+
+    }
+
+    try
+    {
+        DuplicateString(&deviceInfo.contentType, contentType);
+        DuplicateString(&deviceInfo.dateOfManufacture, dateOfManufacture);
+        DuplicateString(&deviceInfo.deviceName, deviceName);
+        DuplicateString(&deviceInfo.deviceUUID, deviceUUID);
+        DuplicateString(&deviceInfo.firmwareVersion, firmwareVersion);
+        DuplicateString(&deviceInfo.hostName, hostName);
+        DuplicateString(&deviceInfo.manufacturerName, manufacturerName);
+        DuplicateString(&deviceInfo.manufacturerUrl, manufacturerUrl);
+        DuplicateString(&deviceInfo.modelNumber, modelNumber);
+        DuplicateString(&deviceInfo.platformVersion, platformVersion);
+        DuplicateString(&deviceInfo.supportUrl, supportUrl);
+        DuplicateString(&deviceInfo.version, version);
+    }catch(exception &e)
+    {
+        std::cout<<"String Copy failed!!\n";
+        return OC_STACK_ERROR;
+    }
+
+    return OC_STACK_OK;
+}
+
+
+
+int main()
+{
+
+    // Create PlatformConfig object
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+        OC::ModeType::Server,
+        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
+        0,         // Uses randomly available port
+        OC::QualityOfService::LowQos
+    };
+
+    OCPlatform::Configure(cfg);
+
+    std::cout<<"Starting server & setting device info\n";
+
+    OCStackResult result = SetDeviceInfo(contentType, dateOfManufacture, deviceName,
+            deviceUUID, firmwareVersion, hostName, manufacturerName, manufacturerUrl,
+            modelNumber, platformVersion, supportUrl, version);
+
+    if(result != OC_STACK_OK)
+    {
+        std::cout << "Device Registration failed\n";
+        return -1;
+    }
+
+    result = OCPlatform::registerDeviceInfo(deviceInfo);
+
+    if(result != OC_STACK_OK)
+    {
+        std::cout << "Device Registration failed\n";
+        return -1;
+    }
+
+    DeleteDeviceInfo();
+
+    // 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);
+
+    // No explicit call to stop the platform.
+    // When OCPlatform::destructor is invoked, internally we do platform cleanup
+
+    return 0;
+
+}
+
+
+
index c97f2aa..6347a6d 100644 (file)
@@ -43,11 +43,11 @@ LIB_OC_LOGGER := ../oc_logger/lib/oc_logger.a
 CXX_LIBS  := ../$(BUILD)/obj/liboc.a ../csdk/$(PLATFORM)/$(BUILD)/liboctbstack.a $(LIB_OC_LOGGER)
 
 # Force metatargets to build:
-all.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient ocicuc_target threadingsample
+all.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient ocicuc_target threadingsample devicediscoveryserver devicediscoveryclient
 
-apps.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample
+apps.PHONY: prep_dirs oc_cpp_sdk simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample devicediscoveryserver devicediscoveryclient
 
-buildScript_all.PHONY: prep_dirs simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample
+buildScript_all.PHONY: prep_dirs simpleserver simpleserverHQ simpleclient simpleclientHQ simpleclientserver roomserver roomclient presenceserver presenceclient garageserver garageclient fridgeserver fridgeclient threadingsample devicediscoveryserver devicediscoveryclient
 
 all: all.PHONY
 
@@ -103,6 +103,12 @@ garageclient: garageclient.cpp
 threadingsample: threadingsample.cpp
        $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ threadingsample.cpp $(CXX_INC) $(CXX_LIBS)
 
+devicediscoveryserver: devicediscoveryserver.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ devicediscoveryserver.cpp $(CXX_INC) $(CXX_LIBS)
+
+devicediscoveryclient: devicediscoveryclient.cpp
+       $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ devicediscoveryclient.cpp $(CXX_INC) $(CXX_LIBS)
+
 ocicuc_target:
        cd ocicuc && $(MAKE) apps
 
index 8ec23a5..1e40e23 100644 (file)
@@ -44,6 +44,10 @@ namespace OC
                         const std::string& resourceType, FindCallback& callback,
                         QualityOfService QoS) = 0;
 
+        virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
+                        const std::string& deviceURI, FindDeviceCallback& callback,
+                        QualityOfService QoS) = 0;
+
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
                         const std::string& uri, const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions,
index 10e0515..c6c0b2d 100644 (file)
@@ -51,6 +51,9 @@ namespace OC
                     EntityHandler& entityHandler,
                     uint8_t resourceProperty) = 0;
 
+        virtual OCStackResult registerDeviceInfo(
+                    const OCDeviceInfo deviceInfo) = 0;
+
         virtual OCStackResult registerResourceWithHost(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceHOST,
index 9ca0779..ced111d 100644 (file)
@@ -52,6 +52,12 @@ namespace OC
             std::weak_ptr<IClientWrapper> clientWrapper;
         };
 
+        struct DeviceListenContext
+        {
+            FindDeviceCallback callback;
+            IClientWrapper::Ptr clientWrapper;
+        };
+
         struct SubscribePresenceContext
         {
             SubscribeCallback callback;
@@ -81,6 +87,10 @@ namespace OC
             const std::string& resourceType, FindCallback& callback,
             QualityOfService QoS);
 
+        virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
+            const std::string& deviceURI, FindDeviceCallback& callback,
+            QualityOfService QoS);
+
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
             const std::string& uri, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions,
index aab856b..b68f599 100644 (file)
@@ -45,6 +45,9 @@ namespace OC
                     EntityHandler& entityHandler,
                     uint8_t resourceProperty);
 
+        virtual OCStackResult registerDeviceInfo(
+                    const OCDeviceInfo deviceInfo);
+
         virtual OCStackResult registerResourceWithHost(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceHOST,
index f46dac0..b523da5 100755 (executable)
@@ -200,6 +200,8 @@ namespace OC
 
     typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback;
 
+    typedef std::function<void(const OCRepresentation&)> FindDeviceCallback;
+
     typedef std::function<OCEntityHandlerResult(
                             const std::shared_ptr<OCResourceRequest>)> EntityHandler;
 
index 61a0f48..1cad339 100644 (file)
@@ -120,6 +120,21 @@ namespace OC
                     FindCallback resourceHandler, QualityOfService QoS);
 
         /**
+         * API for Device Discovery
+         *
+         *
+         * @param host - Host IP Address. If null or empty, Multicast is performed.
+         * @param resourceURI - Uri containing address to the virtual device in C Stack
+                                ("/oc/core/d")
+         * @param QualityOfService the quality of communication
+         *
+         */
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler);
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler, QualityOfService QoS);
+
+        /**
         * This API registers a resource with the server
         * NOTE: This API applies to server side only.
         *
@@ -167,6 +182,18 @@ namespace OC
                         const std::shared_ptr< OCResource > resource);
 
         /**
+         * Register Device Info
+         *
+         * @param deviceInfo - structure containing all the device specific information
+         *
+         * @return
+         *      OC_STACK_OK   - no errors
+         *      OC_STACK_ERROR - stack process error
+         */
+
+        OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo);
+
+        /**
         * Set default device entity handler
         *
         * @param entityHandler - entity handler to handle requests for
index 896ce3a..f25ce2e 100644 (file)
@@ -146,6 +146,21 @@ namespace OC
                     FindCallback resourceHandler, QualityOfService QoS);
 
         /**
+         * API for Device Discovery
+         *
+         * @param host - Host IP Address. If null or empty, Multicast is performed.
+         * @param resourceURI - Uri containing address to the virtual device in C Stack
+         *                       ("/oc/core/d")
+         *
+         * @param QualityOfService the quality of communication
+         *
+         */
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler);
+        OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
+                    FindDeviceCallback deviceInfoHandler, QualityOfService QoS);
+
+        /**
         * This API registers a resource with the server
         * NOTE: This API applies to server side only.
         *
@@ -193,6 +208,17 @@ namespace OC
                         const std::shared_ptr<OCResource> resource);
 
         /**
+         * This API registers all the device specific information
+         *
+         * @param OCDeviceInfo - Structure containing all the device related information
+         *
+         * @return OCStackResult return value of the API. Returns OC_STACK_OK if success
+         *
+         * Note: OCDeviceInfo is defined in OCStack.h
+         */
+        OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo);
+
+        /**
         * Set default device entity handler
         *
         * @param entityHandler - entity handler to handle requests for
index dfae653..049c445 100644 (file)
@@ -36,6 +36,11 @@ namespace OC
             const std::string& resourceType, FindCallback& callback, QualityOfService QoS)
             {return OC_STACK_NOTIMPL;}
 
+        virtual OCStackResult ListenForDevice(const std::string& serviceUrl,
+            const std::string& deviceURI, FindDeviceCallback& callback,
+            QualityOfService QoS)
+            {return OC_STACK_NOTIMPL;}
+
         virtual OCStackResult GetResourceRepresentation(const std::string& host,
             const std::string& uri, const QueryParamsMap& queryParams,
             const HeaderOptions& headerOptions, GetCallback& callback,
index be51f3d..91c6f15 100644 (file)
@@ -43,6 +43,14 @@ namespace OC
             // Not implemented
             return OC_STACK_NOTIMPL;
         }
+
+        virtual OCStackResult registerDeviceInfo(
+                    const OCDeviceInfo deviceInfo)
+        {
+            // Not implemented
+            return OC_STACK_NOTIMPL;
+        }
+
         virtual OCStackResult registerResourceWithHost(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceHOST,
index e9580b2..83e4ef8 100644 (file)
@@ -92,6 +92,33 @@ namespace OC
         }
     }
 
+    OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
+    {
+        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
+        {
+            throw OCException(OC::Exception::STR_NULL_RESPONSE, OC_STACK_ERROR);
+        }
+
+        MessageContainer oc;
+        oc.setJSONRepresentation(clientResponse->resJSONPayload);
+
+        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
+        if(it == oc.representations().end())
+        {
+            throw OCException(OC::Exception::INVALID_REPRESENTATION, OC_STACK_ERROR);
+        }
+
+        // first one is considered the root, everything else is considered a child of this one.
+        OCRepresentation root = *it;
+        ++it;
+
+        std::for_each(it, oc.representations().end(),
+                [&root](const OCRepresentation& repItr)
+                {root.addChild(repItr);});
+        return root;
+
+    }
+
     OCStackApplicationResult listenCallback(void* ctx, OCDoHandle handle,
         OCClientResponse* clientResponse)
     {
@@ -143,7 +170,6 @@ namespace OC
         }
 
         return OC_STACK_KEEP_TRANSACTION;
-
     }
 
     OCStackResult InProcClientWrapper::ListenForResource(const std::string& serviceUrl,
@@ -181,31 +207,52 @@ namespace OC
         return result;
     }
 
-    OCRepresentation parseGetSetCallback(OCClientResponse* clientResponse)
+    OCStackApplicationResult listenDeviceCallback(void* ctx, OCDoHandle handle,
+            OCClientResponse* clientResponse)
     {
-        if(clientResponse->resJSONPayload == nullptr || clientResponse->resJSONPayload[0] == '\0')
-        {
-            return OCRepresentation();
-        }
+        ClientCallbackContext::DeviceListenContext* context =
+            static_cast<ClientCallbackContext::DeviceListenContext*>(ctx);
 
-        MessageContainer oc;
-        oc.setJSONRepresentation(clientResponse->resJSONPayload);
+        OCRepresentation rep = parseGetSetCallback(clientResponse);
+        std::thread exec(context->callback, rep);
+        exec.detach();
 
-        std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
-        if(it == oc.representations().end())
-        {
-            return OCRepresentation();
-        }
+        return OC_STACK_KEEP_TRANSACTION;
+    }
 
-        // first one is considered the root, everything else is considered a child of this one.
-        OCRepresentation root = *it;
-        ++it;
+    OCStackResult InProcClientWrapper::ListenForDevice(const std::string& serviceUrl,
+        const std::string& deviceURI, FindDeviceCallback& callback, QualityOfService QoS)
+    {
+        OCStackResult result;
 
-        std::for_each(it, oc.representations().end(),
-                [&root](const OCRepresentation& repItr)
-                {root.addChild(repItr);});
-        return root;
+        OCCallbackData cbdata = {0};
 
+        ClientCallbackContext::DeviceListenContext* context =
+            new ClientCallbackContext::DeviceListenContext();
+        context->callback = callback;
+        context->clientWrapper = shared_from_this();
+
+        cbdata.context =  static_cast<void*>(context);
+        cbdata.cb = listenDeviceCallback;
+        cbdata.cd = [](void* c){delete static_cast<ClientCallbackContext::DeviceListenContext*>(c);};
+
+        auto cLock = m_csdkLock.lock();
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCDoHandle handle;
+            result = OCDoResource(&handle, OC_REST_GET,
+                                  deviceURI.c_str(),
+                                  nullptr, nullptr,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  NULL, 0);
+        }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
+        return result;
     }
 
     void parseServerHeaderOptions(OCClientResponse* clientResponse,
index 9dbaa27..0159bb8 100755 (executable)
@@ -271,6 +271,18 @@ namespace OC
         }
     }
 
+    OCStackResult InProcServerWrapper::registerDeviceInfo(const OCDeviceInfo deviceInfo)
+    {
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if(cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSetDeviceInfo(deviceInfo);
+        }
+        return result;
+    }
+
     OCStackResult InProcServerWrapper::registerResource(
                     OCResourceHandle& resourceHandle,
                     std::string& resourceURI,
index f26ffc7..9a17833 100644 (file)
@@ -95,6 +95,22 @@ namespace OC
                                                 resourceHandler, QoS);
         }
 
+        OCStackResult getDeviceInfo(const std::string& host,
+                                                const std::string& deviceURI,
+                                                FindDeviceCallback deviceInfoHandler)
+        {
+            return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI, deviceInfoHandler);
+        }
+
+        OCStackResult getDeviceInfo(const std::string& host,
+                                                const std::string& deviceURI,
+                                                FindDeviceCallback deviceInfoHandler,
+                                                QualityOfService QoS)
+        {
+            return OCPlatform_impl::Instance().getDeviceInfo(host, deviceURI,
+                    deviceInfoHandler, QoS);
+        }
+
 
         OCStackResult registerResource(OCResourceHandle& resourceHandle,
                                                 std::string& resourceURI,
@@ -114,6 +130,11 @@ namespace OC
             return OCPlatform_impl::Instance().registerResource(resourceHandle, resource);
         }
 
+        OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo)
+        {
+            return OCPlatform_impl::Instance().registerDeviceInfo(deviceInfo);
+        }
+
         OCStackResult unregisterResource(const OCResourceHandle& resourceHandle)
         {
             return OCPlatform_impl::Instance().unregisterResource(resourceHandle);
index e680943..9d9ae52 100755 (executable)
@@ -172,6 +172,21 @@ namespace OC
                              host, resourceName, resourceHandler, QoS);
     }
 
+    OCStackResult OCPlatform_impl::getDeviceInfo(const std::string& host,
+                                            const std::string& deviceURI,
+                                            FindDeviceCallback deviceInfoHandler)
+    {
+        return result_guard(getDeviceInfo(host, deviceURI, deviceInfoHandler, m_cfg.QoS));
+    }
+
+    OCStackResult OCPlatform_impl::getDeviceInfo(const std::string& host,
+                                            const std::string& deviceURI,
+                                            FindDeviceCallback deviceInfoHandler,
+                                            QualityOfService QoS)
+    {
+        return checked_guard(m_client, &IClientWrapper::ListenForDevice,
+                             host, deviceURI, deviceInfoHandler, QoS);
+    }
 
     OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
                                             std::string& resourceURI,
@@ -185,8 +200,12 @@ namespace OC
                              resourceInterface, entityHandler, resourceProperty);
     }
 
+    OCStackResult OCPlatform_impl::registerDeviceInfo(const OCDeviceInfo deviceInfo)
+    {
+        return checked_guard(m_server, &IServerWrapper::registerDeviceInfo, deviceInfo);
+    }
 
-       OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
+    OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
                                             const std::shared_ptr< OCResource > resource)
     {
         uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
@@ -195,8 +214,8 @@ namespace OC
         return checked_guard(m_server, &IServerWrapper::registerResourceWithHost,
                 ref(resourceHandle), resource->host(), resource->uri(), resourceTypes[0]/*"core.remote"*/, "oc.mi.def",
                 (EntityHandler) nullptr, resourceProperty);
-
     }
+
     OCStackResult OCPlatform_impl::unregisterResource(const OCResourceHandle& resourceHandle) const
     {
         return checked_guard(m_server, &IServerWrapper::unregisterResource,