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
$(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))
return c;
#endif
+ return NULL;
}
void coap_free_context(coap_context_t *context) {
}
return 0;
#endif
+ return 0;
}
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);
case 0x0e:
size++;
/* fall through */
+ continue;
case 0x0d:
size++;
break;
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)
// Typedefs
//-----------------------------------------------------------------------------
-
typedef enum {
OC_COAP_OK = 0,
OC_COAP_ERR
* 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);
*/
int OCProcessCoAP();
+OCCoAPToken * OCGenerateCoAPToken();
#endif /* OCCOAP_H_ */
#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);
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,
// Includes
//=============================================================================
#include "occoap.h"
+#include "occlientcb.h"
#include <coap.h>
#ifndef WITH_ARDUINO
// 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)
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 };
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);
exit:
coap_delete_list(optList);
- OCFree(rcvdToken);
+ if(rcvdToken) {
+ OCFree(rcvdToken);
+ rcvdToken = NULL;
+ }
OCFree(entityHandlerRequest);
OCFree(request);
}
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;
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
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))
{
"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);
}
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]);
}
* 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)
{
}
// 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,
}
// 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;
}
// 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;
*
* 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
*
* @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
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,
// 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;
#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)
*/
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;
/**
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*/
} 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.
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
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;
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.
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
* 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.
+++ /dev/null
-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
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)
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;
OCClientResponse * clientResponse) {
uint8_t remoteIpAddr[4];
uint16_t remotePortNu;
+ OCDoHandle handle;
OC_LOG(INFO, TAG,
"Entering clientApplicationCB (Application Layer CB)");
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;
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*/
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;
return OC_STACK_OK;
}
-
/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
void handleSigInt(int signum) {
if (signum == SIGINT) {
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 !!"));
"/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)
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;
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);
}
}
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);
// Private internal function prototypes
//-----------------------------------------------------------------------------
+OCDoHandle *generateInvocationHandle();
static void initResources();
static void insertResource(OCResource *resource);
static OCResource *findResource(OCResource *resource);
}
/**
- * 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
* 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"));
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;
}
// 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.
*
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;
//-----------------------------------------------------------------------------
// 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.
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);
+ }
}