#include "ocpayload.h"
#include "ocpayloadcbor.h"
#include "cautilinterface.h"
+#include "camessagehandler.h"
#include "oicgroup.h"
#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
static const char COAPS_TCP_SCHEME[] = "coaps+tcp:";
static const char CORESPEC[] = "core";
-CAAdapterStateChangedCB g_adapterHandler = NULL;
-CAConnectionStateChangedCB g_connectionHandler = NULL;
-
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
static OCOtmEventHandler_t g_otmEventHandler = {NULL, NULL};
#endif
+#ifdef WITH_PROCESS_EVENT
+static oc_event g_ocProcessEvent = NULL;
+#endif // WITH_PROCESS_EVENT
+
//-----------------------------------------------------------------------------
// Macros
//-----------------------------------------------------------------------------
static void deleteResourceInterface(OCResourceInterface *resourceInterface);
/**
- * Delete all child resources.
+ * Unbind all child resources.
*
- * @param resourceChild Specified binded resource is deleted from parent.
+ * @param resourceChild Specified binded resource head is deleted from parent.
*/
-static void deleteResourceChild(OCChildResource *resourceChild);
+static void unbindChildResources(OCChildResource *resourceChild);
/**
* Delete all of the dynamically allocated elements that were created for the resource.
case CA_FORBIDDEN_REQ:
ret = OC_STACK_FORBIDDEN_REQ;
break;
+ case CA_TOO_MANY_REQUESTS:
+ ret = OC_STACK_TOO_MANY_REQUESTS;
+ break;
case CA_INTERNAL_SERVER_ERROR:
ret = OC_STACK_INTERNAL_SERVER_ERROR;
break;
case OC_STACK_FORBIDDEN_REQ:
ret = CA_FORBIDDEN_REQ;
break;
+ case OC_STACK_TOO_MANY_REQUESTS:
+ ret = CA_TOO_MANY_REQUESTS;
+ break;
case OC_STACK_INTERNAL_SERVER_ERROR:
ret = CA_INTERNAL_SERVER_ERROR;
break;
OIC_LOG(ERROR, TAG,
"Could not allocate memory for cbNode->presence->timeOut");
OICFree(cbNode->presence);
+ cbNode->presence = NULL;
result = OC_STACK_NO_MEMORY;
goto exit;
}
return;
}
- for (uint8_t i = start; i < responseInfo->info.numOptions; i++)
+ if (response.numRcvdVendorSpecificHeaderOptions > 0)
{
- if(&(responseInfo->info.options[i]))
+ response.rcvdVendorSpecificHeaderOptions =
+ (OCHeaderOption *) OICCalloc(response.numRcvdVendorSpecificHeaderOptions, sizeof(OCHeaderOption));
+ if (NULL == response.rcvdVendorSpecificHeaderOptions)
{
- memcpy (&(response.rcvdVendorSpecificHeaderOptions[i-start]),
- &(responseInfo->info.options[i]), sizeof(OCHeaderOption));
+ OIC_LOG(ERROR, TAG, "Failed to allocate memory for vendor header options");
+ OCPayloadDestroy(response.payload);
+ OICFree((void *)response.resourceUri);
+ return;
}
+
+ memcpy(response.rcvdVendorSpecificHeaderOptions, responseInfo->info.options + start,
+ response.numRcvdVendorSpecificHeaderOptions*sizeof(OCHeaderOption));
}
}
OICFree((void *)response.resourceUri);
OCPayloadDestroy(response.payload);
+ OICFree(response.rcvdVendorSpecificHeaderOptions);
}
return;
}
{
request->requestComplete = 1;
}
+
+ OIC_LOG_V(WARNING, TAG, "Server request ID = [%u]", request->requestId);
}
else
{
OICFree(serverRequest.requestToken);
return;
}
+
serverRequest.numRcvdVendorSpecificHeaderOptions = tempNum;
if (serverRequest.numRcvdVendorSpecificHeaderOptions && requestInfo->info.options)
{
- memcpy (&(serverRequest.rcvdVendorSpecificHeaderOptions), requestInfo->info.options,
+ serverRequest.rcvdVendorSpecificHeaderOptions = (OCHeaderOption*) OICCalloc(tempNum, sizeof(OCHeaderOption));
+ if (NULL == serverRequest.rcvdVendorSpecificHeaderOptions)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to allocated memory to vnd header options!");
+ OICFree(serverRequest.payload);
+ OICFree(serverRequest.requestToken);
+ return;
+ }
+
+ memcpy (serverRequest.rcvdVendorSpecificHeaderOptions, requestInfo->info.options,
sizeof(CAHeaderOption_t)*tempNum);
}
{
OIC_LOG_V(ERROR, TAG, "HandleStackRequests failed. error: %d", requestResult);
+ // Delete observer node if it is OBSERVE failure from app
+ if (serverRequest.observationOption == OC_OBSERVE_REGISTER)
+ {
+ DeleteObserverUsingToken(requestInfo->info.token, requestInfo->info.tokenLength);
+ }
+
CAResponseResult_t stackResponse =
OCToCAStackResult(requestResult, serverRequest.method);
// The token is copied in there, and is thus still owned by this function.
OICFree(serverRequest.payload);
OICFree(serverRequest.requestToken);
+ OICFree(serverRequest.rcvdVendorSpecificHeaderOptions);
OIC_LOG(INFO, TAG, "Exit OCHandleRequests");
}
}
#endif
- InitializeObseverList();
+ InitializeObserverList();
exit:
if(result != OC_STACK_OK)
TerminateScheduleResourceList();
// Remove all observers
- TerminateObserverList();
+ DeleteObserverList();
// Free memory dynamically allocated for resources
deleteAllResources();
// Remove all the client callbacks
// TODO after BeachHead delivery: consolidate into single SRMDeInit()
SRMDeInitPolicyEngine();
+ // Destroy Observer List Mutex
+ TerminateObserverList();
+
stackState = OC_STACK_UNINITIALIZED;
return OC_STACK_OK;
}
goto exit;
}
+ cbData = NULL; // Client CB list entry now owns it
+ token = NULL; // Client CB list entry now owns it
devAddr = NULL; // Client CB list entry now owns it
resourceUri = NULL; // Client CB list entry now owns it
resourceType = NULL; // Client CB list entry now owns it
{
*handle = resHandle;
}
+#ifdef WITH_PROCESS_EVENT
+ OCSendProcessEventSignal();
+#endif // WITH_PROCESS_EVENT
goto exit;
}
if (result != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCDoResource error");
+ if (NULL != cbData && NULL != cbData->cd)
+ {
+ cbData->cd(cbData->context);
+ }
FindAndDeleteClientCB(clientCB);
CADestroyToken(token);
if (handle)
CopyDevAddrToEndpoint(clientCB->devAddr, &endpoint);
- if ((endpoint.adapter & CA_ADAPTER_IP) && qos != OC_HIGH_QOS)
+ if (((endpoint.adapter & CA_ADAPTER_IP) && qos != OC_HIGH_QOS) ||
+ ((endpoint.adapter & CA_ADAPTER_TCP) && OC_LOW_QOS_WITH_TCP == qos))
{
+ OIC_LOG_V(INFO, TAG, "the %s observe callback is removed", clientCB->requestUri);
FindAndDeleteClientCB(clientCB);
break;
}
#ifdef WITH_PRESENCE
-OCStackResult OCProcessPresence()
+#ifdef WITH_PROCESS_EVENT
+OCStackResult OCProcessPresence(uint32_t *nextEventTime)
+#else // WITH_PROCESS_EVENT
+OCStackResult OCProcessPresence(void)
+#endif // !WITH_PROCESS_EVENT
{
OCStackResult result = OC_STACK_OK;
// to most purposes. Uncomment as needed.
//OIC_LOG(INFO, TAG, "Entering RequestPresence");
ClientCB* cbNode = NULL;
+ ClientCB* tempcbNode = NULL;
OCClientResponse clientResponse;
OCStackApplicationResult cbResult = OC_STACK_DELETE_TRANSACTION;
- LL_FOREACH(cbList, cbNode)
+ LL_FOREACH_SAFE(cbList, cbNode, tempcbNode)
{
if (OC_REST_PRESENCE != cbNode->method || !cbNode->presence)
{
{
FindAndDeleteClientCB(cbNode);
}
+ continue;
}
- if (now < cbNode->presence->timeOut[cbNode->presence->TTLlevel])
+ uint32_t timeout = cbNode->presence->timeOut[cbNode->presence->TTLlevel];
+ if (now < timeout)
{
+#ifdef WITH_PROCESS_EVENT
+ if (nextEventTime && (timeout - now) < *nextEventTime)
+ {
+ *nextEventTime = timeout - now;
+ }
+#endif // WITH_PROCESS_EVENT
continue;
}
}
#endif // WITH_PRESENCE
+#ifdef WITH_PROCESS_EVENT
+OCStackResult OCProcess(void)
+{
+ uint32_t nextEventTime;
+ return OCProcessEvent(&nextEventTime);
+}
+
+OCStackResult OCProcessEvent(uint32_t *nextEventTime)
+{
+ if (stackState == OC_STACK_UNINITIALIZED)
+ {
+ OIC_LOG(ERROR, TAG, "OCProcess has failed. ocstack is not initialized");
+ return OC_STACK_ERROR;
+ }
+
+ *nextEventTime = UINT32_MAX;
+
+#ifdef WITH_PRESENCE
+ OCProcessPresence(nextEventTime);
+ OIC_LOG_V(INFO, TAG, "OCProcessPresence next event time : %u", *nextEventTime);
+#endif
+ CAHandleRequestResponse();
+
+// TODO
+#ifdef ROUTING_GATEWAY
+ RMProcess(nextEventTime);
+#endif
+
+#ifdef TCP_ADAPTER
+ OCProcessKeepAlive(nextEventTime);
+ OIC_LOG_V(INFO, TAG, "OCProcessKeepAlive next event time : %u", *nextEventTime);
+#endif
+ return OC_STACK_OK;
+}
+
+void OCRegisterProcessEvent(oc_event event)
+{
+ g_ocProcessEvent = event;
+ CARegisterProcessEvent(event);
+}
+
+void OCSendProcessEventSignal(void)
+{
+ if (g_ocProcessEvent)
+ {
+ oc_event_signal(g_ocProcessEvent);
+ }
+}
+#else // WITH_PROCESS_EVENT
+
OCStackResult OCProcess()
{
if (stackState == OC_STACK_UNINITIALIZED)
#endif
return OC_STACK_OK;
}
+#endif // !WITH_PROCESS_EVENT
#ifdef WITH_PRESENCE
OCStackResult OCStartPresence(const uint32_t ttl)
return result;
}
+OCStackResult OCResetResourceTypes(OCResourceHandle handle,
+ const char *newResourceType)
+{
+ OCStackResult result = OC_STACK_ERROR;
+ OCResource *resource = NULL;
+
+ resource = findResource((OCResource *) handle);
+ if (!resource)
+ {
+ OIC_LOG(ERROR, TAG, "Resource not found");
+ return OC_STACK_ERROR;
+ }
+
+ // Clear all bound resource types
+ deleteResourceType(resource->rsrcType);
+ resource->rsrcType = NULL;
+
+ // Bind new resource type to resource
+ result = BindResourceTypeToResource(resource, newResourceType);
+
+#ifdef WITH_PRESENCE
+ if(presenceResource.handle)
+ {
+ ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
+ }
+#endif
+
+ return result;
+}
+
OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle,
const char *resourceInterfaceName)
{
return result;
}
+OCStackResult OCResetResourceInterfaces(OCResourceHandle handle,
+ const char *newResourceInterface)
+{
+ OCStackResult result = OC_STACK_ERROR;
+ OCResource *resource = NULL;
+
+ resource = findResource((OCResource *) handle);
+ if (!resource)
+ {
+ OIC_LOG(ERROR, TAG, "Resource not found");
+ return OC_STACK_ERROR;
+ }
+
+ // Clear all bound interface
+ deleteResourceInterface(resource->rsrcInterface);
+ resource->rsrcInterface = NULL;
+
+ // Bind new interface to resource
+ result = BindResourceInterfaceToResource(resource, newResourceInterface);
+
+#ifdef WITH_PRESENCE
+ if (presenceResource.handle)
+ {
+ ((OCResource *)presenceResource.handle)->sequenceNum = OCGetRandom();
+ SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_CHANGE);
+ }
+#endif
+
+ return result;
+}
+
OCStackResult OCGetNumberOfResources(uint8_t *numResources)
{
OCResource *pointer = headResource;
SendPresenceNotification(resource->rsrcType, OC_PRESENCE_TRIGGER_DELETE);
}
#endif
+ // Delete resource's all observers
+ DeleteObserverUsingResource(resource);
+
// Only resource in list.
if (temp == headResource && temp == tailResource)
{
}
if (resource->rsrcChildResourcesHead)
{
- deleteResourceChild(resource->rsrcChildResourcesHead);
+ unbindChildResources(resource->rsrcChildResourcesHead);
resource->rsrcChildResourcesHead = NULL;
}
if (resource->rsrcAttributes)
OCDeleteResourceAttributes(resource->rsrcAttributes);
resource->rsrcAttributes = NULL;
}
+
+ resource->entityHandler = NULL;
resource = NULL;
}
}
}
-void deleteResourceChild(OCChildResource *resourceChild)
+void unbindChildResources(OCChildResource *head)
{
OCChildResource *next = NULL;
- for (OCChildResource *pointer = resourceChild; pointer; pointer = next)
+ for (OCChildResource *current = head; current; current = next)
{
- next = pointer->next ? pointer->next : NULL;
- if (pointer->rsrcResource)
- {
- deleteResourceElements(pointer->rsrcResource);
- pointer->rsrcResource = NULL;
- }
- OICFree(pointer);
+ next = current->next;
+ OICFree(current);
}
}
#endif
OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID,
- void* optionData, size_t optionDataLength)
+ const void* optionData, size_t optionDataLength)
{
if (!ocHdrOpt)
{
void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
{
OIC_LOG(DEBUG, TAG, "OCDefaultAdapterStateChangedHandler");
- if (g_adapterHandler)
- {
- g_adapterHandler(adapter, enabled);
- }
+
+ OC_UNUSED(adapter);
+ OC_UNUSED(enabled);
}
void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected)
{
OIC_LOG(DEBUG, TAG, "OCDefaultConnectionStateChangedHandler");
- if (g_connectionHandler)
- {
- g_connectionHandler(info, isConnected);
- }
/*
* If the client observes one or more resources over a reliable connection,
return ret;
}
+OCStackResult OCGetDeviceOperationalState(bool* isOp)
+{
+ if(NULL != isOp)
+ {
+ *isOp = GetPstatIsop();
+ return OC_STACK_OK;
+ }
+
+ return OC_STACK_ERROR;
+}
+
void OCClearCallBackList()
{
DeleteClientCBList();