Enabling Requests on Multiple Interfaces CA
authoromkar <omkar.m.hegde@intel.com>
Thu, 8 Jan 2015 01:00:38 +0000 (17:00 -0800)
committeromkar <omkar.m.hegde@intel.com>
Mon, 12 Jan 2015 21:15:36 +0000 (13:15 -0800)
Updated sample apps to send Discovery messages
over multiple interfaces.
Unicast Messages are sent over WIFI.
Added a new type "OC_ALL" for Multicast messages.
Resource Discovery is not done in case of multicast
device discovery.

Change-Id: Ifb3364b986e588bd95ae255acaf913ffc7f49fcc
Signed-off-by: omkar <omkar.m.hegde@intel.com>
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/oicgroup.c

index 437d596..6fdfe57 100644 (file)
@@ -138,10 +138,11 @@ typedef enum {
  * Adaptor types
  */
 typedef enum {
-    OC_ETHERNET = (1 << 0),
-    OC_WIFI = (1 << 1),
-    OC_EDR = (1 << 2),
-    OC_LE = (1 << 3)
+    OC_ETHERNET = 0,
+    OC_WIFI,
+    OC_EDR,
+    OC_LE,
+    OC_ALL //Multicast message: send over all the interfaces.
 } OCConnectivityType;
 #endif
 
index e9e1228..4067497 100644 (file)
@@ -34,6 +34,13 @@ 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";
+#ifdef CA_INT
+static const char * MULTICAST_DEVICE_DISCOVERY_QUERY = "/oc/core/d";
+static const char * MULTICAST_RESOURCE_DISCOVERY_QUERY = "/oc/core";
+//The following variable determines the interface (wifi, ethernet etc.)
+//to be used for sending unicast messages. Default set to WIFI.
+static OCConnectivityType CA_CONNTYPE = OC_WIFI;
+#endif
 static std::string putPayload = "{\"state\":\"on\",\"power\":5}";
 static std::string coapServerIP = "255.255.255.255";
 static std::string coapServerPort = "5683";
@@ -62,8 +69,15 @@ void handleSigInt(int signum) {
 
 static void PrintUsage()
 {
-    OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3|4|5|6|7>");
+#ifdef CA_INT
+    OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3|4|5|6|7> -c <0|1|2|3>");
+#else
+     OC_LOG(INFO, TAG, "Usage : occlient -u <0|1> -t <1|2|3|4|5|6|7>");
+#endif
     OC_LOG(INFO, TAG, "-u <0|1> : Perform multicast/unicast discovery of resources");
+#ifdef CA_INT
+    OC_LOG(INFO, TAG, "-c <0|1|2|3> : Send unicast messages over Ethernet, WIFI, EDR or LE");
+#endif
     OC_LOG(INFO, TAG, "-t 1  :  Discover Resources");
     OC_LOG(INFO, TAG, "-t 2  :  Discover Resources and Initiate Nonconfirmable Get Request");
     OC_LOG(INFO, TAG, "-t 3  :  Discover Resources and Initiate Nonconfirmable Put Requests");
@@ -107,7 +121,7 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
 #ifdef CA_INT
     ret = OCDoResource(&handle, method, query.str().c_str(), 0,
                        (method == OC_REST_PUT) ? putPayload.c_str() : NULL,
-                       (OC_WIFI), qos, &cbData, options, numOptions);
+                       (CA_CONNTYPE), qos, &cbData, options, numOptions);
 #else
     ret = OCDoResource(&handle, method, query.str().c_str(), 0,
                        (method == OC_REST_PUT) ? putPayload.c_str() : NULL,
@@ -576,15 +590,30 @@ int InitDeviceDiscovery()
         strncpy(szQueryUri, TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY,
                         (strlen(TEST_APP_UNICAST_DEVICE_DISCOVERY_QUERY) + 1));
     }
+
     else
     {
+#ifdef CA_INT
+        strncpy(szQueryUri, MULTICAST_DEVICE_DISCOVERY_QUERY,
+                (strlen(MULTICAST_DEVICE_DISCOVERY_QUERY) + 1));
+
+#else
         strncpy(szQueryUri, TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY,
                 (strlen(TEST_APP_MULTICAST_DEVICE_DISCOVERY_QUERY) + 1));
+#endif
     }
 
 #ifdef CA_INT
-    ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, (OC_WIFI),
-                        OC_LOW_QOS, &cbData, NULL, 0);
+    if(UNICAST_DISCOVERY)
+    {
+        ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, CA_CONNTYPE,
+                OC_LOW_QOS, &cbData, NULL, 0);
+    }
+    else
+    {
+        ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, (OC_ALL),
+                OC_LOW_QOS, &cbData, NULL, 0);
+    }
 #else
     ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, OC_LOW_QOS, &cbData, NULL, 0);
 #endif
@@ -604,25 +633,34 @@ int InitDiscovery()
     OCDoHandle handle;
     /* Start a discovery query*/
     char szQueryUri[64] = { 0 };
+
     if (UNICAST_DISCOVERY)
     {
         strcpy(szQueryUri, TEST_APP_UNICAST_DISCOVERY_QUERY);
     }
     else
     {
-    #ifdef CA_INT
-        // TODO-CA CA is using 5298 for MC. Why 5298?
-        strcpy(szQueryUri, "coap://224.0.1.187:5298/oc/core");
-    #else
+#ifdef CA_INT
+        strcpy(szQueryUri, MULTICAST_RESOURCE_DISCOVERY_QUERY);
+#else
         strcpy(szQueryUri, OC_WELL_KNOWN_QUERY);
-    #endif
+#endif
     }
+
     cbData.cb = discoveryReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 #ifdef CA_INT
-    ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, (OC_ETHERNET | OC_WIFI),
-                        OC_LOW_QOS, &cbData, NULL, 0);
+    if(UNICAST_DISCOVERY)
+    {
+        ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, CA_CONNTYPE,
+                OC_LOW_QOS, &cbData, NULL, 0);
+    }
+    else
+    {
+        ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, (OC_ALL),
+                OC_LOW_QOS, &cbData, NULL, 0);
+    }
 #else
     ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, OC_LOW_QOS, &cbData, NULL, 0);
 #endif
@@ -640,7 +678,11 @@ int main(int argc, char* argv[]) {
     uint8_t ifname[] = "eth0";
     int opt;
 
+#ifdef CA_INT
+    while ((opt = getopt(argc, argv, "u:t:c:")) != -1)
+#else
     while ((opt = getopt(argc, argv, "u:t:")) != -1)
+#endif
     {
         switch(opt)
         {
@@ -650,6 +692,11 @@ int main(int argc, char* argv[]) {
             case 't':
                 TEST_CASE = atoi(optarg);
                 break;
+            #ifdef CA_INT
+            case 'c':
+                CA_CONNTYPE = OCConnectivityType(atoi(optarg));
+                break;
+            #endif
             default:
                 PrintUsage();
                 return -1;
@@ -679,7 +726,14 @@ int main(int argc, char* argv[]) {
         return 0;
     }
 
-    InitDiscovery();
+    if(UNICAST_DISCOVERY  == 0  && TEST_CASE == TEST_DISCOVER_DEV_REQ)
+    {
+        InitDeviceDiscovery();
+    }
+    else
+    {
+        InitDiscovery();
+    }
 
     // Break from loop with Ctrl+C
     OC_LOG(INFO, TAG, "Entering occlient main loop...");
index c32deb9..b2c2c74 100644 (file)
@@ -238,15 +238,76 @@ OCStackResult CAToOCStackResult(CAResponseResult_t caCode)
     return ret;
 }
 
+OCStackResult OCToCAConnectivityType(OCConnectivityType ocConType, CAConnectivityType_t* caConType)
+{
+    OCStackResult ret = OC_STACK_OK;
+
+    switch(ocConType)
+    {
+        case OC_ETHERNET:
+            *caConType = CA_ETHERNET;
+            break;
+        case OC_WIFI:
+            *caConType = CA_WIFI;
+            break;
+        case OC_EDR:
+            *caConType = CA_EDR;
+            break;
+        case OC_LE:
+            *caConType = CA_LE;
+            break;
+        case OC_ALL:
+            //TODO-CA Add other connectivity types as they are enabled
+            *caConType = (CA_WIFI|CA_ETHERNET);
+            break;
+        default:
+            ret = OC_STACK_INVALID_PARAM;
+            break;
+    }
+    return ret;
+}
+
+OCStackResult CAToOCConnectivityType(CAConnectivityType_t caConType, OCConnectivityType *ocConType)
+{
+    OCStackResult ret = OC_STACK_OK;
+
+    switch(caConType)
+    {
+        case CA_ETHERNET:
+            *ocConType = OC_ETHERNET;
+            break;
+        case CA_WIFI:
+            *ocConType = OC_WIFI;
+            break;
+        case CA_EDR:
+            *ocConType = OC_EDR;
+            break;
+        case CA_LE:
+            *ocConType = OC_LE;
+            break;
+        default:
+            ret = OC_STACK_INVALID_PARAM;
+            break;
+    }
+    return ret;
+}
+
 // update response.addr appropriately from endPoint.addressInfo
-void UpdateResponseAddr(OCClientResponse *response, const CARemoteEndpoint_t* endPoint)
+OCStackResult UpdateResponseAddr(OCClientResponse *response, const CARemoteEndpoint_t* endPoint)
 {
     struct sockaddr_in sa;
+    OCStackResult ret = OC_STACK_INVALID_PARAM;
+    //TODO-CA Check validity of the endPoint pointer
     inet_pton(AF_INET, endPoint->addressInfo.IP.ipAddress, &(sa.sin_addr));
     sa.sin_port = htons(endPoint->addressInfo.IP.port);
     static OCDevAddr address;
     memcpy((void*)&address.addr, &(sa), sizeof(sa));
-    response->addr = &address;
+    if(response)
+    {
+        response->addr = &address;
+        ret = CAToOCConnectivityType(endPoint->connectivityType, &(response->connType));
+    }
+    return ret;
 }
 
 void HandlePresenceResponse(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
@@ -258,7 +319,11 @@ void HandlePresenceResponse(const CARemoteEndpoint_t* endPoint, const CAResponse
     char * bufRes = responseInfo->info.payload;
     OCClientResponse *response = (OCClientResponse *) OCMalloc(sizeof(OCClientResponse));
 
-    UpdateResponseAddr(response, endPoint);
+    OCStackResult result = UpdateResponseAddr(response, endPoint);
+    if(result != OC_STACK_OK)
+    {
+        goto exit;
+    }
 
     if(!bufRes)
     {
@@ -335,8 +400,12 @@ void HandleCAResponses(const CARemoteEndpoint_t* endPoint, const CAResponseInfo_
         OC_LOG(INFO, TAG, PCF("Calling into application address space"));
         OCClientResponse response;
 
-        UpdateResponseAddr(&response, endPoint);
-        response.connType = endPoint->connectivityType;
+        OCStackResult result = UpdateResponseAddr(&response, endPoint);
+        if(result != OC_STACK_OK)
+        {
+            OC_LOG(ERROR, TAG, PCF("Invalid connectivity type in endpoint"));
+            return;
+        }
 
         response.result = CAToOCStackResult(responseInfo->result);
         response.resJSONPayload = (unsigned char*)responseInfo->info.payload;
@@ -1182,6 +1251,9 @@ OCStackResult verifyUriQueryLength(const char *inputUri, uint16_t uriLen)
  *     OC_STACK_INVALID_CALLBACK - invalid callback function pointer
  *     OC_STACK_INVALID_METHOD   - invalid resource method
  *     OC_STACK_INVALID_URI      - invalid required or reference URI
+ *
+ * Note: IN case of CA, when using multicast, the required URI should not contain IP address.
+ *       Instead, it just contains the URI to the resource such as "/oc/core".
  */
 #ifdef CA_INT
 OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requiredUri,
@@ -1349,17 +1421,6 @@ OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requ
         result = OC_STACK_INVALID_PARAM;
         goto exit;
     }
-    // TODO-CA: Handle multi-cast scenario
-    // Create remote end point
-    caResult = CACreateRemoteEndpoint(newUri, conType, &endpoint);
-    // TODO-CA: Connectivity type should be passed to API
-    endpoint->connectivityType = conType;
-
-    if (caResult != CA_STATUS_OK)
-    {
-        OC_LOG(ERROR, TAG, PCF("CACreateRemoteEndpoint error"));
-        goto exit;
-    }
 
     // create token
     caResult = CAGenerateToken(&caToken);
@@ -1399,21 +1460,38 @@ OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requ
 
     requestInfo.info = requestData;
 
+    CAConnectivityType_t caConType;
+
+    result = OCToCAConnectivityType(conType, &caConType);
+    if (result != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, PCF("Invalid Connectivity Type"));
+        goto exit;
+    }
+
     // send request
-    //TODO-CA Change This logic. Currently hardcoded to WIFI & ETHERNET
-    //Need to support other adapter types.
-    if(conType == (CA_WIFI | CA_ETHERNET))
+    if(conType == OC_ALL)
     {
-        //TODO-CA remove hardcoded resource uri. Instead, extract it from newUri
-        grpEnd.connectivityType = conType;
-        grpEnd.resourceUri = "/oc/core";
+        grpEnd.connectivityType = caConType;
+
+        grpEnd.resourceUri = (CAURI_t) OICMalloc(uriLen + 1);
+        strncpy(grpEnd.resourceUri, requiredUri, (uriLen + 1));
 
         caResult = CASendRequestToAll(&grpEnd, &requestInfo);
     }
     else
     {
+        caResult = CACreateRemoteEndpoint(newUri, caConType, &endpoint);
+
+        if (caResult != CA_STATUS_OK)
+        {
+            OC_LOG(ERROR, TAG, PCF("CACreateRemoteEndpoint error"));
+            goto exit;
+        }
+
         caResult = CASendRequest(endpoint, &requestInfo);
     }
+
     if (caResult != CA_STATUS_OK)
     {
         OC_LOG(ERROR, TAG, PCF("CASendRequest"));
@@ -1456,6 +1534,7 @@ exit:
     }
 #ifdef CA_INT
     CADestroyRemoteEndpoint(endpoint);
+    OCFree(grpEnd.resourceUri);
     if (hdrOptionMemAlloc)
     {
         OCFree(requestData.options);
index 5592ede..731c404 100644 (file)
@@ -680,7 +680,7 @@ OCStackResult SendAction(OCDoHandle *handle, const char *targetUri, const unsign
 #ifdef CA_INT
     return OCDoResource(handle, OC_REST_PUT, targetUri,
     //temp->rsrcType->resourcetypename,
-            NULL, (char *) action, OC_WIFI | OC_ETHERNET, OC_NA_QOS, &cbdata, NULL, 0);
+            NULL, (char *) action, OC_WIFI, OC_NA_QOS, &cbdata, NULL, 0);
 #else
     return OCDoResource(handle, OC_REST_PUT, targetUri,
     //temp->rsrcType->resourcetypename,