Added API enum for removing observation of servers' resource.
authorJoseph Morrow <joseph.l.morrow@intel.com>
Sun, 3 Aug 2014 00:05:05 +0000 (20:05 -0400)
committerGerrit Code Review <gerrit@fmygit6002.fm.intel.com>
Mon, 4 Aug 2014 19:14:49 +0000 (12:14 -0700)
Turned out to be a very minimal change to the public API.

Added more changes to fulfill callback management requirements. (i.e. Token in/out on OCDoResource())

Reverted Token implementation. Defined "OCDoHandle"

Turned off many over-zealous ignore-warning flags. Fixed few errors that arose with that.

Made fixes to all modules (minus libcoap, which didnt need it) to get the stack to build with new infrastructure (i.e. baggage of maintaining ODDoHandle) in place.

Rebased on top of Sachin's changeset. Made changes so that the stack and apps build and compile.

Sachin made changes to a makefile. I rebased onto his patch set #6.

Changed "eth3" to "eth0" in sample apps. Turned tabs into spaces.

Somehow 'OCDoHandle' was commented out in my changeset? Well, I uncommented it out and it builds again. Logging ONLY works with "make BUILD=debug" now. I assume this is in alignment with Sachin's changes. -- So no worries on logging?

Implementation of send observe request in place now.

Change-Id: I93140cafc1dd51ba35fb47b1fb455fef7a95499a

19 files changed:
csdk/libcoap-4.1.1/makefile
csdk/libcoap-4.1.1/net.c
csdk/makefile
csdk/occoap/include/occoap.h
csdk/occoap/include/occoaphelper.h
csdk/occoap/src/occoap.c
csdk/occoap/src/occoaphelper.c
csdk/stack/include/internal/occlientcb.h
csdk/stack/include/internal/ocserverrequest.h
csdk/stack/include/internal/ocstackinternal.h
csdk/stack/include/ocstack.h
csdk/stack/samples/SimpleClientServer/client.txt [deleted file]
csdk/stack/samples/SimpleClientServer/makefile
csdk/stack/samples/SimpleClientServer/occlient.cpp
csdk/stack/samples/SimpleClientServer/ocserver.cpp
csdk/stack/src/occlientcb.c
csdk/stack/src/ocresource.c
csdk/stack/src/ocserverrequest.c
csdk/stack/src/ocstack.c

index d560c72..e16fe54 100644 (file)
@@ -46,10 +46,9 @@ else
    $(error Wrong value for PLATFORM !!)
 endif
 
-CC_FLAGS.debug := -O0 -g3 -Wall -Wno-write-strings -ffunction-sections -fdata-sections -fno-exceptions \
-       -Wextra -Wno-variadic-macros -pedantic -std=gnu99 -DTB_LOG
-CC_FLAGS.release := -Os -Wall -Wno-write-strings -ffunction-sections -fdata-sections -fno-exceptions \
-       -Wextra -Wno-variadic-macros -pedantic -std=gnu99
+CC_FLAGS.debug := -O0 -g3 -Wall -ffunction-sections -fdata-sections -fno-exceptions -pedantic \
+-std=gnu99 -DTB_LOG
+CC_FLAGS.release := -Os -Wall -ffunction-sections -fdata-sections -fno-exceptions -std=gnu99 \
 
 CFLAGS         += $(CC_FLAGS.$(BUILD))
 
index 681be28..97819b2 100644 (file)
@@ -428,6 +428,7 @@ coap_new_context(const coap_address_t *listen_addr) {
 
     return c;
 #endif
+    return NULL;
 }
 
 void coap_free_context(coap_context_t *context) {
@@ -485,6 +486,7 @@ int coap_join_wellknown_group(coap_context_t *ctx,
     }
     return 0;
 #endif
+    return 0;
 }
 
 int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu,
@@ -503,7 +505,7 @@ int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu,
          * the largest known option, we know that everything beyond is
          * bad.
          */
-        if (opt_iter.type & 0x01
+        if ((opt_iter.type & 0x01)
                 && coap_option_getb(ctx->known_options, opt_iter.type) < 1) {
             debug("unknown critical option %d\n", opt_iter.type);
 
@@ -1125,6 +1127,7 @@ coap_new_error_response(coap_pdu_t *request, unsigned char code,
         case 0x0e:
             size++;
             /* fall through */
+            continue;
         case 0x0d:
             size++;
             break;
index 88cb164..e715b71 100644 (file)
@@ -42,7 +42,8 @@ INC_DIRS      += -I$(OCTBSTACK_INC)
 INC_DIRS       += -I$(OCTBSTACK_INC)/internal
 INC_DIRS       += -I$(CJSON_INC)
 
-CC_FLAGS.debug         := -O0 -g3 -Wall -c -fmessage-length=0 -pedantic -std=c99 -fpic -DTB_LOG
+CC_FLAGS.debug         := -O0 -g3 -Wall -c -fmessage-length=0 -pedantic -std=c99 -fpic \
+                       -DTB_LOG
 CC_FLAGS.release       := -Os -Wall -c -fmessage-length=0 -std=c99 -fpic
 
 CFLAGS         += $(CC_FLAGS.$(BUILD)) -DWITH_POSIX $(INC_DIRS)
index fa51271..0554cb5 100644 (file)
@@ -33,7 +33,6 @@
 // Typedefs
 //-----------------------------------------------------------------------------
 
-
 typedef enum {
     OC_COAP_OK = 0,
     OC_COAP_ERR
@@ -72,7 +71,7 @@ int OCInitCoAP(const char *address, uint16_t port, OCMode mode);
  *   0   - success
  *   TBD - TBD error
  */
-int OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCToken * token,
+int OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPToken * token,
                      const char *Uri, const char *payload);
 
 
@@ -91,5 +90,6 @@ int OCStopCoAP();
  */
 int OCProcessCoAP();
 
+OCCoAPToken * OCGenerateCoAPToken();
 
 #endif /* OCCOAP_H_ */
index 9cf7df8..2efae66 100644 (file)
 #include <limits.h>
 #include <ctype.h>
 
+#define MAX_TOKEN_LENGTH (8)
+
+typedef struct {
+    uint8_t token[MAX_TOKEN_LENGTH];
+    size_t tokenLength;
+} OCCoAPToken;
+
 // Convert OCStack code to CoAP code
 uint8_t OCToCoAPResponseCode(OCStackResult result);
 
@@ -60,8 +67,8 @@ OCStackResult FormOCEntityHandlerRequest(const coap_queue_t * rcvdRequest,
         unsigned char * bufRes, unsigned char * query);
 
 // Internal function to retrieve a Token from received coap pdu
-OCStackResult RetrieveOCToken(const coap_queue_t * rcvdRequest,
-        OCToken * * rcvdTokenLoc);
+OCStackResult RetrieveOCCoAPToken(const coap_queue_t * rcvdRequest,
+        OCCoAPToken * * rcvdTokenLoc);
 
 // Internal function to create OCResponse struct at the client from a received coap pdu
 OCStackResult FormOCResponse(const coap_queue_t * rcvdResponse,
index cc9cfd5..3efc09a 100644 (file)
@@ -23,6 +23,7 @@
 // Includes
 //=============================================================================
 #include "occoap.h"
+#include "occlientcb.h"
 #include <coap.h>
 
 #ifndef WITH_ARDUINO
@@ -54,6 +55,19 @@ static coap_context_t *gCoAPCtx = NULL;
 // Helper Functions
 //=============================================================================
 
+//generate a coap token
+OCCoAPToken * OCGenerateCoAPToken() {
+    OCCoAPToken *token;
+    // Generate token here, it will be deleted when the transaction is deleted
+    token = (OCCoAPToken *) malloc(sizeof(OCCoAPToken));
+    token->tokenLength = MAX_TOKEN_LENGTH;
+    OCFillRandomMem((uint8_t*)token->token, token->tokenLength);
+
+    //OC_LOG_V(INFO,TAG,"Toke n generated %d bytes..........%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+    //         token->tokenLength,token->token[0],token->token[1],token->token[2],token->token[3],
+    //         token->token[4],token->token[5],token->token[6],token->token[7]);
+    return token;
+}
 //This function is called back by libcoap when a request is received
 static void HandleCoAPRequests(struct coap_context_t *ctx,
         const coap_queue_t * rcvdRequest)
@@ -64,7 +78,7 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
     OCStackResult result;
     OCRequest * request = NULL;
     OCEntityHandlerRequest * entityHandlerRequest = NULL;
-    OCToken * rcvdToken = NULL;
+    OCCoAPToken * rcvdToken = NULL;
 
     unsigned char rcvdUri[MAX_URI_LENGTH] = { 0 };
     unsigned char rcvdQuery[MAX_QUERY_LENGTH] = { 0 };
@@ -85,21 +99,22 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
             bufRes, rcvdQuery);
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
-    // fill OCToken structure
-    result = RetrieveOCToken(rcvdRequest, &rcvdToken);
+    // fill OCCoAPToken structure
+    result = RetrieveOCCoAPToken(rcvdRequest, &rcvdToken);
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
-    // put everything together
-    entityHandlerRequest->token = rcvdToken;
     request->entityHandlerRequest = entityHandlerRequest;
 
     OC_LOG_V(INFO, TAG, " Receveid uri:     %s", request->resourceUrl);
     OC_LOG_V(INFO, TAG, " Receveid query:   %s", entityHandlerRequest->query);
     OC_LOG_V(INFO, TAG, " Receveid payload: %s",
             request->entityHandlerRequest->reqJSONPayload);
-    OC_LOG_V(INFO, TAG, " Token received %d bytes",
-            rcvdToken->tokenLength);
-    OC_LOG_BUFFER(INFO, TAG, rcvdToken->token, rcvdToken->tokenLength );
+
+    if(GetClientCB(rcvdToken, 0)) { //True if the token was found in the list of clientCBs
+        OC_LOG_V(INFO, TAG, " Token received %d bytes",
+                rcvdToken->tokenLength);
+        OC_LOG_BUFFER(INFO, TAG, rcvdToken->token, rcvdToken->tokenLength);
+    }
 
     // process the request
     result = HandleStackRequests(request);
@@ -143,7 +158,10 @@ static void HandleCoAPRequests(struct coap_context_t *ctx,
 
 exit:
     coap_delete_list(optList);
-    OCFree(rcvdToken);
+    if(rcvdToken) {
+        OCFree(rcvdToken);
+        rcvdToken = NULL;
+    }
     OCFree(entityHandlerRequest);
     OCFree(request);
 }
@@ -152,7 +170,7 @@ exit:
 static void HandleCoAPResponses(struct coap_context_t *ctx,
         const coap_queue_t * rcvdResponse) {
     OCResponse * response = NULL;
-    OCToken * token = NULL;
+    OCCoAPToken * _token = NULL;
     OCClientResponse * clientResponse = NULL;
     OCStackResult result;
 
@@ -167,8 +185,8 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
         result = FormOCResponse(rcvdResponse, &response);
         VERIFY_SUCCESS(result, OC_STACK_OK);
 
-        // fill OCToken structure
-        result = RetrieveOCToken(rcvdResponse, &token);
+        // fill OCCoAPToken structure
+        result = RetrieveOCCoAPToken(rcvdResponse, &_token);
         VERIFY_SUCCESS(result, OC_STACK_OK);
 
         // fill OCClientResponse structure
@@ -176,15 +194,21 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
         VERIFY_SUCCESS(result, OC_STACK_OK);
 
         // put everything together
-        response->token = token;
+        ClientCB * clientCB = GetClientCB(_token, NULL);
+        OCDoHandle *handle = NULL;
+        if(clientCB) {
+            handle = clientCB->handle;
+            response->handle = handle;
+        }
         response->clientResponse = clientResponse;
 
         OC_LOG_V(INFO, TAG, " Received a response HandleCoAPResponses in occoap: %s",
                  response->clientResponse->resJSONPayload);
-        OC_LOG_V(INFO, TAG,"Token received %d bytes", response->token->tokenLength);
-        OC_LOG_BUFFER(INFO, TAG, response->token->token,
-                      response->token->tokenLength);
-               response->clientResponse->result = OC_STACK_OK;
+        OC_LOG_V(INFO, TAG,"Token received %d bytes", _token->tokenLength);
+        OC_LOG_BUFFER(INFO, TAG, _token->token,
+                      _token->tokenLength);
+
+        response->clientResponse->result = OC_STACK_OK;
         HandleStackResponses(response);
         /*if (rcvdResponse->pdu->hdr->code == COAP_RESPONSE_CODE(205))
         {
@@ -197,14 +221,17 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
                    "No other response codes are supported in HandleCoAPResponses");
         }*/
     }
-       else
-       {
+    else
+    {
         OC_LOG(DEBUG, TAG, "Do not accept other than NON in HandleCoAPResponses");
     }
 
 exit:
     OCFree(response);
-    OCFree(token);
+    if(_token) {
+        OCFree(_token);
+        _token = NULL;
+    }
     OCFree(clientResponse);
 }
 
@@ -243,9 +270,9 @@ int OCInitCoAP(const char *address, uint16_t port, OCMode mode) {
     if (address)
     {
         if (!ParseIPv4Address((unsigned char *) address, ipAddr))
-               {
-               return OC_COAP_ERR;
-           }
+        {
+            return OC_COAP_ERR;
+        }
         OC_LOG_V(INFO, TAG, "Parsed IP Address %d.%d.%d.%d",ipAddr[0],ipAddr[1],ipAddr[2],ipAddr[3]);
     }
 
@@ -284,7 +311,7 @@ exit:
  *   0   - success
  *   TBD - TBD error
  */
-int OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCToken * token,
+int OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPToken * token,
                      const char *Uri, const char *payload)
 {
 
@@ -370,10 +397,34 @@ int OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCToken * token,
     }
 
     // Decide method type
-    if (method != OC_REST_GET && method != OC_REST_PUT) {
-        OC_LOG(FATAL, TAG, "OCDoCoAPResource only supports GET/PUT method");
+    switch (method) {
+        case OC_REST_GET:
+            coapMethod = COAP_REQUEST_GET;
+            break;
+        case OC_REST_PUT:
+            coapMethod = COAP_REQUEST_PUT;
+            break;
+        case OC_REST_OBSERVE_ALL:
+        case OC_REST_OBSERVE:
+            coapMethod = COAP_REQUEST_GET;
+            buflen = BUF_SIZE;
+            buf = _buf;
+            res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
+            //Set observe option flag.
+            while (res--) {
+                coap_insert(&optList,
+                        CreateNewOptionNode(COAP_OPTION_SUBSCRIPTION,
+                                COAP_OPT_LENGTH(buf), COAP_OPT_VALUE(buf)),
+                        OrderOptions);
+
+                buf += COAP_OPT_SIZE(buf);
+            }
+            break;
+        default:
+            coapMethod = 0;
+            OC_LOG(FATAL, TAG, "OCDoCoAPResource only supports GET, PUT, & OBSERVE methods");
+            break;
     }
-    coapMethod = (method == OC_REST_GET) ? COAP_REQUEST_GET : COAP_REQUEST_PUT;
 
     VERIFY_NON_NULL(gCoAPCtx);
     pdu = GenerateCoAPPdu(coapMsgType, coapMethod,
index 20047d2..49d1ed2 100644 (file)
@@ -164,11 +164,11 @@ OCStackResult FormOCEntityHandlerRequest(const coap_queue_t * rcvdRequest,
 }
 
 // Retrieve the token from the PDU
-OCStackResult RetrieveOCToken(const coap_queue_t * rcvdRequest,
-        OCToken * * rcvdTokenLoc) {
-    OCToken * rcvdToken = NULL;
+OCStackResult RetrieveOCCoAPToken(const coap_queue_t * rcvdRequest,
+        OCCoAPToken * * rcvdTokenLoc) {
+    OCCoAPToken * rcvdToken = NULL;
 
-    rcvdToken = (OCToken *) OCMalloc(sizeof(OCToken));
+    rcvdToken = (OCCoAPToken *) OCMalloc(sizeof(OCCoAPToken));
     if (!rcvdToken) {
         return OC_STACK_NO_MEMORY;
     }
index a301db2..f33762f 100644 (file)
@@ -31,7 +31,11 @@ typedef struct ClientCB {
     // callback context data
     void * context;
     //  when a response is recvd with this token, above callback will be invoked
-    OCToken * token;
+    OCCoAPToken * token;
+    // Invocation handle tied to original call to OCDoResource()
+    OCDoHandle * handle;
+    // This is used to determine if all responses should be consumed or not. (For now, only pertains to OC_REST_OBSERVE_ALL Vs. OC_REST_OBSERVE functionality)
+    OCMethod method;
     // next node in this list
     struct ClientCB    *next;
 } ClientCB;
@@ -41,15 +45,21 @@ typedef struct ClientCB {
  *
  * This method is used to add a client callback method in cbList.
  *
+ * @param[out] clientCB
+ *              The resulting node from making this call. Null if out of memory.
  * @param[in] cb
  *              address to client callback function.
- * @param[out] token
- *              address to token.
+ * @param[in] token
+ *              identifier for OTA CoAP comms.
+ * @param[in] handle
+ *              Masked in the public API as an 'invocation handle' - Used for callback management.
+ *
+ * @brief If the handle you're looking for does not exist, the stack will reply with a RST message.
  *
- * @retval 0 for Success, otherwise some error value
+ * @retval OC_STACK_OK for Success, otherwise some error value
  */
 //------------------------------------------------------------------------
-OCStackResult AddClientCB(OCCallbackData *cbData, OCToken * token);
+OCStackResult AddClientCB(ClientCB* clientCB, OCCallbackData *cbData, OCCoAPToken * token, OCDoHandle * handle, OCMethod method);
 
 //-- DeleteClientCB -----------------------------------------------------------
 /** @ingroup ocstack
@@ -70,11 +80,15 @@ void DeleteClientCB(ClientCB *cbNode);
  *
  * @param[in] token
  *              token to search for.
+ * @param[in] handle
+ *              handle to search for.
+ *
+ * @brief You can search by token OR by handle. Not both.
  *
  * @retval address of the node if found, otherwise NULL
  */
 //------------------------------------------------------------------------
-ClientCB* GetClientCB(OCToken * token);
+ClientCB* GetClientCB(OCCoAPToken * token, OCDoHandle * handle);
 
 //-- DeleteClientCBList -----------------------------------------------------------
 /** @ingroup ocstack
index 7c1a99d..f950d4b 100644 (file)
@@ -35,7 +35,7 @@ typedef enum {
     STACK_RES_DISCOVERY_RT_FILTER
 } StackQueryTypes;
 
-OCStackResult ProcessResourceDiscoverReq (const char *request, char *response,
+OCStackResult ProcessResourceDiscoverReq (const unsigned char *request, unsigned char *response,
                                  uint8_t filterOn, char *filterValue);
 
 OCStackResult ValidateUrlQuery (unsigned char *url, unsigned char *query,
index d9b7af3..89c89a9 100644 (file)
@@ -128,8 +128,8 @@ typedef struct {
 
 // following structure will be created in occoap and passed up the stack on the client side
 typedef struct {
-    // token is copied from the received response PDU
-    OCToken * token;
+    // handle is retrieved by comparing the token-handle pair in the PDU.
+    OCDoHandle * handle;
     // this structure will be passed to client
     OCClientResponse * clientResponse;
 } OCResponse;
index 4cb474d..dd57c8b 100644 (file)
@@ -39,7 +39,6 @@ extern "C" {
 #define OC_MULTICAST_PREFIX                  PCF("coap://224.0.1.187:5683")
 
 #define USE_RANDOM_PORT (0)
-#define MAX_TOKEN_LENGTH (8)
 #define MAX_RESPONSE_LENGTH (128)
 #define MAX_REQUEST_LENGTH (128)
 #define MAX_URI_LENGTH (64)
@@ -65,11 +64,12 @@ typedef enum {
  */
 typedef enum {
     OC_REST_NOMETHOD = 0,
-    OC_REST_GET      = (1 << 0),  // Read
-    OC_REST_PUT      = (1 << 1),  // Write
-    OC_REST_POST     = (1 << 2),  // Update
-    OC_REST_DELETE   = (1 << 3),  // Delete
-    OC_REST_OBSERVE  = (1 << 4)   // Register observe request
+    OC_REST_GET      = (1 << 0),      // Read
+    OC_REST_PUT      = (1 << 1),      // Write
+    OC_REST_POST     = (1 << 2),      // Update
+    OC_REST_DELETE   = (1 << 3),      // Delete
+    OC_REST_OBSERVE  = (1 << 4),      // Register observe request for most up date notifications ONLY.
+    OC_REST_OBSERVE_ALL  = (1 << 5)   // Register observe request for all notifications, including stale notifications.
 } OCMethod;
 
 /**
@@ -110,9 +110,9 @@ typedef enum {
     OC_STACK_INVALID_PORT,
     OC_STACK_INVALID_CALLBACK,
     OC_STACK_INVALID_METHOD,
+    OC_STACK_INVALID_PARAM,
     OC_STACK_NO_MEMORY,
     OC_STACK_COMM_ERROR,
-    OC_STACK_INVALID_PARAM,
     OC_STACK_NOTIMPL,
     OC_STACK_NO_RESOURCE, /* resource not found*/
     OC_STACK_RESOURCE_ERROR, /*ex: not supported method or interface*/
@@ -121,15 +121,15 @@ typedef enum {
 } OCStackResult;
 
 /**
+ * Handle to an @ref OCDoResource invocation.
+ */
+typedef void * OCDoHandle;
+
+/**
  * Handle to an OCResource object owned by the OCStack.
  */
 typedef void * OCResourceHandle;
 
-typedef struct {
-    uint8_t token[MAX_TOKEN_LENGTH];
-    size_t tokenLength;
-} OCToken;
-
 /**
  * Incoming requests handled by the server. Requests are passed in as a parameter to the @ref OCEntityHandler callback API.
  * @brief The @ref OCEntityHandler callback API must be implemented in the application in order to receive these requests.
@@ -143,8 +143,6 @@ typedef struct {
     OCMethod method;
     // reqJSON is retrieved from the payload of the received request PDU
     unsigned const char * reqJSONPayload;
-    // token is copied from the received request PDU
-    OCToken * token;
     // resJSON is allocated in the stack and will be used by entity handler to fill in its response
     unsigned char * resJSONPayload;
     // Length of maximum allowed response
@@ -159,6 +157,8 @@ typedef struct {
     OCStackResult result;
     // Address of remote server
     OCDevAddr * addr;
+    // If associated with observe, this will represent the sequence of notifications from server.
+    uint8_t sequenceNumber;
     // resJSONPayload is retrieved from the payload of the received request PDU
     unsigned  const char * resJSONPayload;
 }OCClientResponse;
@@ -193,8 +193,6 @@ typedef struct {
     OCClientResponseHandler cb;
 } OCCallbackData;
 
-
-
 /**
  * Application server implementations must implement this callback to consume requests OTA.
  * TODO: Need a clear explanation that the Entity handler callback needs to fill in the data inside the OCEntityHandlerRequest and then simply return from the callback.
@@ -241,9 +239,10 @@ OCStackResult OCStop();
 OCStackResult OCProcess();
 
 /**
- * Discover OC resources.
+ * Discover or Perform requests on a specified resource (specified by that Resource's respective URI).
  *
- * @param method             - method to perform on the resource
+ * @param handle             - @ref OCDoHandle to refer to the request sent out on behalf of calling this API.
+ * @param method             - @ref OCMethod to perform on the resource
  * @param requiredUri        - URI of the resource to interact with
  * @param referenceUri       - URI of the reference resource
  * @param request            - JSON encoded request
@@ -257,10 +256,19 @@ OCStackResult OCProcess();
  *     OC_STACK_INVALID_METHOD   - invalid resource method
  *     OC_STACK_INVALID_URI      - invalid required or reference URI
  */
-OCStackResult OCDoResource(OCMethod method, const char  *requiredUri, const char  *referenceUri,
+OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char  *requiredUri, const char  *referenceUri,
                 const char *request, OCQualityOfService qos, OCCallbackData *cbData);
 
-
+/**
+ * Cancel a request associated with a specific @ref OCDoResource invocation.
+ *
+ * @param handle - Used to identify a specific OCDoResource invocation.
+ *
+ * @return
+ *     OC_STACK_OK               - No errors; Success
+ *     OC_STACK_INVALID_PARAM    - The handle provided is invalid.
+ */
+OCStackResult OCCancel(OCDoHandle handle);
 
 /**
  * Create a resource.
diff --git a/csdk/stack/samples/SimpleClientServer/client.txt b/csdk/stack/samples/SimpleClientServer/client.txt
deleted file mode 100644 (file)
index d522894..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-INFO: occlient: Starting occlient on address 
-INFO: OCStack: Entering OCInit
-INFO: OCStack: IP Address = 
-INFO: OCStack: Client mode
-INFO: OCCoAP: Entering OCInitCoAP
-INFO: OCCoAP: Parsed IP Address 0.0.0.0
-DEBUG: ocsocket: OCInitUDP Begin
-DEBUG: ocsocket: OCInitUDP End
-INFO: OCStack: Entering OCDoResource
-INFO: OCStack: Token generated 8 bytes..........9e:10:4a:13:a3:a1:a6:ab
-INFO: OCCoAP: Entering OCDoCoAPResource
-INFO: OCCoAP: URI = coap://224.0.1.187:5683/oc/core?rt=core.led
-DEBUG: OCCoAP: uri.host.s 224.0.1.187:5683/oc/core?rt=core.led
-DEBUG: OCCoAP: uri.path.s oc/core?rt=core.led
-DEBUG: OCCoAP: uri.port 5683
-DEBUG: OCCoAP: uri.query.s rt=core.led
-v:1 t:1 tkl:8 c:1 id:58622
-DEBUG: ocsocket: OCSendTo Begin
-DEBUG: ocsocket: OCSendTo End
-bytes_written 32
-INFO: OCCoAP: TID 41504
-INFO: OCCoAP: Deleting PDU
-INFO: OCCoAP: Done Deleting PDU
-INFO: OCStack: Done with this function
-INFO: occlient: Entering occlient main loop...
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:36 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:37 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:38 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:39 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:40 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:41 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:42 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:43 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:44 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:45 DEBG coap_read: discarded invalid frame
-INFO: OCStack: Entering OCProcess
-INFO: OCCoAP: Entering OCProcessCoAP
-DEBUG: ocsocket: OCRecvFrom Begin
-DEBUG: ocsocket: No data to read
-Jul 21 15:43:46 DEBG coap_read: discarded invalid frame
-INFO: occlient: Exiting occlient main loop...
-INFO: OCStack: Entering OCStop
-INFO: OCCoAP: Entering OCStopCoAP
index 9ee98ad..59fcf76 100644 (file)
@@ -31,10 +31,10 @@ INC_DIRS    += -I$(LCOAP_INC)
 INC_DIRS       += -I$(OCCOAP_INC)
 INC_DIRS       += -I$(OCTBSTACK_INC)
 
-CC_FLAGS.debug                 := -O0 -g3 -Wall -Wno-write-strings -ffunction-sections -fdata-sections -fno-exceptions \
-                                       -Wextra -Wno-variadic-macros -pedantic $(INC_DIRS) -L$(ROOT_DIR) -DTB_LOG
-CC_FLAGS.release       := -Os -Wall -Wno-write-strings -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-s -fno-exceptions \
-                                       -Wextra -Wno-variadic-macros $(INC_DIRS) -L$(ROOT_DIR) -DTB_LOG
+CC_FLAGS.debug      := -O0 -g3 -Wall -ffunction-sections -fdata-sections -fno-exceptions \
+                        -pedantic $(INC_DIRS) -L$(ROOT_DIR) -DTB_LOG
+CC_FLAGS.release    := -Os -Wall -fdata-sections -Wl,--gc-sections -Wl,-s -fno-exceptions \
+                        $(INC_DIRS) -L$(ROOT_DIR) -DTB_LOG
                                        
 LDLIBS         += -loctbstack
 CPPFLAGS       += $(CC_FLAGS.$(BUILD)) $(LDLIBS)
index 7aff421..8938506 100644 (file)
@@ -71,10 +71,10 @@ OCStackApplicationResult clientApplicationGETCb(void* ctx, OCClientResponse * cl
                OCCallbackData cbData;
                cbData.cb = clientApplicationPUTCb;
                cbData.context = (void*)CTX_VAL;
-               //OCDoHandle handle;
+               OCDoHandle handle;
 
                OC_LOG_V(INFO, TAG, "PUT payload from client = %s ", putPayload.c_str());       
-               if (OCDoResource(OC_REST_PUT, getQuery.str().c_str(), 0, putPayload.c_str(), OC_NON_CONFIRMABLE, &cbData)
+               if (OCDoResource(&handle, OC_REST_PUT, getQuery.str().c_str(), 0, putPayload.c_str(), OC_NON_CONFIRMABLE, &cbData)
                                != OC_STACK_OK) {
                        OC_LOG_V(ERROR, TAG, "OCStack resource error");
                        //reOC_LOG_Vturn 0;
@@ -89,6 +89,7 @@ OCStackApplicationResult clientApplicationCB(void* ctx,
         OCClientResponse * clientResponse) {
     uint8_t remoteIpAddr[4];
     uint16_t remotePortNu;
+    OCDoHandle handle;
 
     OC_LOG(INFO, TAG,
             "Entering clientApplicationCB (Application Layer CB)");
@@ -114,7 +115,7 @@ OCStackApplicationResult clientApplicationCB(void* ctx,
        OCCallbackData cbData;
        cbData.cb = clientApplicationGETCb;
        cbData.context = (void*)CTX_VAL;
-       if (OCDoResource(OC_REST_GET, getQuery.str().c_str(), 0, 0, OC_NON_CONFIRMABLE, &cbData)
+       if (OCDoResource(&handle, OC_REST_GET, getQuery.str().c_str(), 0, 0, OC_NON_CONFIRMABLE, &cbData)
                        != OC_STACK_OK) {
                OC_LOG(ERROR, TAG, "OCStack resource error");
                //return 0;
@@ -130,6 +131,7 @@ int main() {
        uint16_t port = USE_RANDOM_PORT;
        uint8_t ifname[] = "eth0";
        OCCallbackData cbData;
+    OCDoHandle handle;
 
        /*Get Ip address on defined interface and initialize coap on it with random port number
         * this port number will be used as a source port in all coap communications*/
@@ -151,7 +153,7 @@ int main() {
        strcpy(szQueryUri, OC_WELL_KNOWN_QUERY);
        cbData.cb = clientApplicationCB;
        cbData.context = (void*)CTX_VAL;
-       if (OCDoResource(OC_REST_GET, szQueryUri, 0, 0, OC_NON_CONFIRMABLE, &cbData)
+       if (OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, OC_NON_CONFIRMABLE, &cbData)
                        != OC_STACK_OK) {
                OC_LOG(ERROR, TAG, "OCStack resource error");
                return 0;
index ee9b50d..e2035e4 100644 (file)
@@ -80,7 +80,6 @@ OCStackResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest
        return OC_STACK_OK;
 }
 
-
 /* SIGINT handler: set gQuitFlag to 1 for graceful termination */
 void handleSigInt(int signum) {
        if (signum == SIGINT) {
index 8f48b01..298d2cf 100644 (file)
 
 static struct ClientCB *cbList = NULL;
 
-OCStackResult AddClientCB(OCCallbackData* cbData, OCToken * token) {
+OCStackResult AddClientCB(ClientCB* clientCB, OCCallbackData* cbData, OCCoAPToken * token, OCDoHandle * handle, OCMethod method) {
     ClientCB *cbNode;
     cbNode = (ClientCB*) OCMalloc(sizeof(ClientCB));
     if (cbNode) {
         cbNode->callBack = cbData->cb;
         cbNode->context = cbData->context;
         cbNode->token = token;
+        cbNode->handle = handle;
+        cbNode->method = method;
         LL_APPEND(cbList, cbNode);
+        clientCB = cbNode;
         return OC_STACK_OK;
     }
+    clientCB = NULL;
     return OC_STACK_NO_MEMORY;
 }
 
 void DeleteClientCB(ClientCB * cbNode) {
-    LL_DELETE(cbList, cbNode);
-    OCFree(cbNode->token);
-    OCFree(cbNode);
+    if(cbNode) {
+        LL_DELETE(cbList, cbNode);
+        if(cbNode->token) {
+            OCFree(cbNode->token);
+            cbNode->token = NULL;
+        }
+        OCFree(cbNode);
+        cbNode = NULL;
+    }
 }
 
-ClientCB* GetClientCB(OCToken *token) {
-    ClientCB* out;
-    LL_FOREACH(cbList, out) {
-        if((out->token->tokenLength == token->tokenLength) && (memcmp(out->token->token, token->token, token->tokenLength) == 0) ) {
-            return out;
+ClientCB* GetClientCB(OCCoAPToken * token, OCDoHandle * handle) {
+    ClientCB* out = NULL;
+    if(token) {
+        LL_FOREACH(cbList, out) {
+            if((out->token->tokenLength == token->tokenLength) && (memcmp(out->token->token, token->token, token->tokenLength) == 0) ) {
+                return out;
+            }
+        }
+    }
+    else if(handle) {
+        LL_FOREACH(cbList, out) {
+            if(memcmp(out->handle, handle, sizeof(OCDoHandle)) == 0) {
+                return out;
+            }
         }
     }
     OC_LOG(INFO, MOD_NAME, PCF("Callback Not found !!"));
index 3855766..fdaf8fd 100644 (file)
@@ -36,7 +36,7 @@ static const char * VIRTUAL_RSRCS[] = {
        "/oc/core/types/d",
 };
 
-TODO ("Does it make sense to make this method as inline");
+TODO ("Does it make sense to make this method as inline")
 const char * GetVirtualResourceUri( OCVirtualResources resource)
 {
     if (resource < OC_MAX_RESOURCES)
index e11f392..84721f4 100644 (file)
@@ -36,7 +36,7 @@
 
 extern OCResource *headResource;
 
-OCStackResult ProcessResourceDiscoverReq (const char *request, char *response,
+OCStackResult ProcessResourceDiscoverReq (const unsigned char *request, unsigned char *response,
                                  uint8_t filterOn, char *filterValue)
 {
     OCResource *resourcePtr = headResource;
index bc0ac8d..f881bb2 100644 (file)
@@ -78,8 +78,8 @@ OCStackResult HandleStackRequests(OCRequest * request) {
         if (result == OC_STACK_OK)
         {
             result = ProcessResourceDiscoverReq(
-                    (const char*) request->entityHandlerRequest->reqJSONPayload,
-                    (char *) request->entityHandlerRequest->resJSONPayload, filterOn,
+                    (const unsigned char*) request->entityHandlerRequest->reqJSONPayload,
+                    (unsigned char *) request->entityHandlerRequest->resJSONPayload, filterOn,
                     filterValue);
         }
     }
@@ -110,7 +110,7 @@ void HandleStackResponses(OCResponse * response) {
         OC_LOG(DEBUG, TAG, "The response has an error, should we do anything?");
     }
 
-    cbNode = GetClientCB(response->token);
+    cbNode = GetClientCB(NULL, response->handle);
     if (cbNode) {
         OC_LOG(INFO, TAG, PCF("Calling into application address space"));
         result = cbNode->callBack(cbNode->context, response->clientResponse);
@@ -161,6 +161,7 @@ int ParseIPv4Address(unsigned char * ipAddrStr, uint8_t * ipAddr) {
 // Private internal function prototypes
 //-----------------------------------------------------------------------------
 
+OCDoHandle *generateInvocationHandle();
 static void initResources();
 static void insertResource(OCResource *resource);
 static OCResource *findResource(OCResource *resource);
@@ -269,14 +270,15 @@ OCStackResult OCStop() {
 }
 
 /**
- * Discover OC resources.
+ * Discover or Perform requests on a specified resource (specified by that Resource's respective URI).
  *
- * @param method             - method to perform on the resource
+ * @param handle             - @ref OCDoHandle to refer to the request sent out on behalf of calling this API.
+ * @param method             - @ref OCMethod to perform on the resource
  * @param requiredUri        - URI of the resource to interact with
  * @param referenceUri       - URI of the reference resource
  * @param request            - JSON encoded request
  * @param qos                - quality of service
- * @param asyncApplicationCB - asynchronous callback function that is invoked
+ * @param cbData             - struct that contains asynchronous callback function that is invoked
  *                             by the stack when discovery or resource interaction is complete
  *
  * @return
@@ -286,11 +288,13 @@ OCStackResult OCStop() {
  *     OC_STACK_INVALID_URI      - invalid required or reference URI
  */
 
-OCStackResult OCDoResource(OCMethod method, const char *requiredUri,
+OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requiredUri,
                            const char *referenceUri, const char *request,
                            OCQualityOfService qos, OCCallbackData *cbData)
 {
-    OCToken * token;
+    OCDoHandle * _handle;
+    OCCoAPToken * _token;
+    ClientCB *clientCB = NULL;
     (void) referenceUri;
 
     OC_LOG(INFO, TAG, PCF("Entering OCDoResource"));
@@ -299,12 +303,22 @@ OCStackResult OCDoResource(OCMethod method, const char *requiredUri,
     VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
     VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
 
+    _handle = generateInvocationHandle();
+    *handle = *_handle;
+    _token = OCGenerateCoAPToken();
+    if(AddClientCB(clientCB, cbData, _token, handle, method) != OC_STACK_OK) {
+        return OC_STACK_NO_MEMORY;
+    }
+
     switch (method)
     {
         case OC_REST_GET:
         case OC_REST_PUT:
+        case OC_REST_OBSERVE:
+        case OC_REST_OBSERVE_ALL:
             break;
         default:
+            DeleteClientCB(clientCB);
             return OC_STACK_INVALID_METHOD;
     }
 
@@ -312,29 +326,39 @@ OCStackResult OCDoResource(OCMethod method, const char *requiredUri,
     // Validate required URI
     VERIFY_NON_NULL(requiredUri, FATAL, OC_STACK_INVALID_URI);
 
-    // Generate token here, it will be deleted when the transaction is deleted
-    token = (OCToken *) malloc(sizeof(OCToken));
-    VERIFY_NON_NULL(token, FATAL, OC_STACK_NO_MEMORY);
-
-    token->tokenLength = MAX_TOKEN_LENGTH;
-    OCFillRandomMem(token->token, token->tokenLength);
-    OC_LOG_BUFFER(INFO,TAG, token->token, token->tokenLength);
-
     // Make call to OCCoAP layer
-    if (OCDoCoAPResource(method, qos, token, requiredUri, request) == OC_COAP_OK) {
+    if (OCDoCoAPResource(method, qos, _token, requiredUri, request) == OC_COAP_OK) {
         OC_LOG(INFO, TAG, "Done with this function");
-        if (AddClientCB(cbData, token) == OC_STACK_OK)
-        {
-            return OC_STACK_OK;
-        }
+        return OC_STACK_OK;
     }
 
     OC_LOG(ERROR, TAG, PCF("Stack stop error"));
-    free(token);
+    DeleteClientCB(clientCB);
     return OC_STACK_ERROR;
 }
 
 /**
+ * Cancel a request associated with a specific @ref OCDoResource invocation.
+ *
+ * @param handle - Used to identify a specific OCDoResource invocation.
+ *
+ * @return
+ *     OC_STACK_OK               - No errors; Success
+ *     OC_STACK_INVALID_PARAM    - The handle provided is invalid.
+ */
+OCStackResult OCCancel(OCDoHandle handle) {
+    if(!handle) {
+        return OC_STACK_INVALID_PARAM;
+    }
+    ClientCB *clientCB = GetClientCB(NULL, handle);
+    if(clientCB) {
+        DeleteClientCB(clientCB);
+        return OC_STACK_OK;
+    }
+    return OC_STACK_INVALID_PARAM;
+}
+
+/**
  * Called in main loop of OC client or server.  Allows low-level processing of
  * stack services.
  *
@@ -455,13 +479,13 @@ OCStackResult OCCreateResource(OCResourceHandle *handle,
         OC_LOG(ERROR, TAG, PCF("Error adding resourceinterface"));
         goto exit;
     }
-
-       // added [CL]
-       result = OCBindResourceHandler((OCResourceHandle) pointer, entityHandler);
-       if (result != OC_STACK_OK) {
-               OC_LOG(ERROR, TAG, PCF("Error adding resourceinterface"));
-               goto exit;
-       }
+    
+    // added [CL]
+    result = OCBindResourceHandler((OCResourceHandle) pointer, entityHandler);
+    if (result != OC_STACK_OK) {
+        OC_LOG(ERROR, TAG, PCF("Error adding resourceinterface"));
+        goto exit;
+    }
 
     *handle = pointer;
     result = OC_STACK_OK;
@@ -1046,6 +1070,19 @@ OCStackResult OCNotifyObservers(OCResourceHandle handle) {
 //-----------------------------------------------------------------------------
 // Private internal function definitions
 //-----------------------------------------------------------------------------
+/**
+ * Generate handle of OCDoResource invocation for callback management.
+ */
+OCDoHandle *generateInvocationHandle() {
+    OCDoHandle *handle = NULL;
+    uint8_t val = sizeof(uint8_t[MAX_TOKEN_LENGTH]);
+    // Generate token here, it will be deleted when the transaction is deleted
+    handle = (OCDoHandle *) malloc(sizeof(uint8_t[MAX_TOKEN_LENGTH]));
+    memset(handle, 0, sizeof(uint8_t[MAX_TOKEN_LENGTH]));
+    OCFillRandomMem((uint8_t*)handle, val);
+
+    return handle;
+}
 
 /**
  * Initialize resource data structures, variables, etc.
@@ -1308,6 +1345,8 @@ void *OCMalloc(size_t size) {
 
 void OCFree(void *ptr) {
     TODO ("This should be moved into an ocmalloc dir and implemented as a separate OC module");
-    free(ptr);
+    if(ptr) {
+        free(ptr);
+    }
 }