static CAResult_t OCSelectNetwork();
/**
- * Get the CoAP ticks after the specified number of milli-seconds.
- *
- * @param afterMilliSeconds Milli-seconds.
- * @return
- * CoAP ticks
- */
-static uint32_t GetTicks(uint32_t afterMilliSeconds);
-
-/**
- * Convert CAResult_t to OCStackResult.
- *
- * @param caResult CAResult_t code.
- * @return ::OC_STACK_OK on success, some other value upon failure.
- */
-static OCStackResult CAResultToOCStackResult(CAResult_t caResult);
-
-/**
* Convert CAResponseResult_t to OCStackResult.
*
* @param caCode CAResponseResult_t code.
return false;
}
-uint32_t GetTicks(uint32_t afterMilliSeconds)
+uint32_t GetTicks(uint32_t milliSeconds)
{
coap_tick_t now;
coap_ticks(&now);
// Guard against overflow of uint32_t
- if (afterMilliSeconds <= ((UINT32_MAX - (uint32_t)now) * MILLISECONDS_PER_SECOND) /
+ if (milliSeconds <= ((UINT32_MAX - (uint32_t)now) * MILLISECONDS_PER_SECOND) /
COAP_TICKS_PER_SECOND)
{
- return now + (afterMilliSeconds * COAP_TICKS_PER_SECOND)/MILLISECONDS_PER_SECOND;
+ return now + (milliSeconds * COAP_TICKS_PER_SECOND)/MILLISECONDS_PER_SECOND;
}
else
{
if(observer)
{
result = FormOCEntityHandlerRequest(&ehRequest,
- (OCRequestHandle)NULL,
+ 0,
OC_REST_NOMETHOD,
&observer->devAddr,
(OCResourceHandle)NULL,
if(observer->failedCommCount >= MAX_OBSERVER_FAILED_COMM)
{
result = FormOCEntityHandlerRequest(&ehRequest,
- (OCRequestHandle)NULL,
+ 0,
OC_REST_NOMETHOD,
&observer->devAddr,
(OCResourceHandle)NULL,
else
{
observer->failedCommCount++;
+ observer->forceHighQos = 1;
+ OIC_LOG_V(DEBUG, TAG, "Failed count for this observer is %d",
+ observer->failedCommCount);
result = OC_STACK_CONTINUE;
}
- observer->forceHighQos = 1;
- OIC_LOG_V(DEBUG, TAG, "Failed count for this observer is %d",observer->failedCommCount);
}
break;
default:
return result;
}
-static OCStackResult CAResultToOCStackResult(CAResult_t caResult)
-{
- OCStackResult ret = OC_STACK_ERROR;
-
- switch(caResult)
- {
- case CA_ADAPTER_NOT_ENABLED:
- case CA_SERVER_NOT_STARTED:
- ret = OC_STACK_ADAPTER_NOT_ENABLED;
- break;
- case CA_MEMORY_ALLOC_FAILED:
- ret = OC_STACK_NO_MEMORY;
- break;
- case CA_STATUS_INVALID_PARAM:
- ret = OC_STACK_INVALID_PARAM;
- break;
- default:
- break;
- }
- return ret;
-}
-
OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode)
{
OCStackResult ret = OC_STACK_ERROR;
}
}
-/**
- * Encode an address string to match RFC 6874.
- *
- * @param outputAddress a char array to be written with the encoded string.
- *
- * @param outputSize size of outputAddress buffer.
- *
- * @param inputAddress a char array of size <= CA_MAX_URI_LENGTH
- * containing a valid IPv6 address string.
- *
- * @return OC_STACK_OK if encoding succeeded.
- * Else an error occured.
- */
- OCStackResult encodeAddressForRFC6874(char *outputAddress,
- size_t outputSize,
- const char *inputAddress)
+OCStackResult OCEncodeAddressForRFC6874(char *outputAddress,
+ size_t outputSize,
+ const char *inputAddress)
{
VERIFY_NON_NULL(inputAddress, FATAL, OC_STACK_INVALID_PARAM);
VERIFY_NON_NULL(outputAddress, FATAL, OC_STACK_INVALID_PARAM);
if (inputSize > outputSize)
{
OIC_LOG_V(ERROR, TAG,
- "encodeAddressForRFC6874 failed: "
+ "OCEncodeAddressForRFC6874 failed: "
"outputSize (%zu) < inputSize (%zu)",
outputSize, inputSize);
// If no string follows the first '%', then the input was invalid.
if (scopeIdPart[0] == '\0')
{
- OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: Invalid input string: no scope ID!");
+ OIC_LOG(ERROR, TAG, "OCEncodeAddressForRFC6874 failed: Invalid input string: no scope ID!");
return OC_STACK_ERROR;
}
// Check to see if the string is already encoded
if ((scopeIdPart[0] == '2') && (scopeIdPart[1] == '5'))
{
- OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: Input string is already encoded");
+ OIC_LOG(ERROR, TAG, "OCEncodeAddressForRFC6874 failed: Input string is already encoded");
return OC_STACK_ERROR;
}
// Fail if we don't have room for encoded string's two additional chars
if (outputSize < (inputSize + 2))
{
- OIC_LOG(ERROR, TAG, "encodeAddressForRFC6874 failed: encoded output will not fit!");
+ OIC_LOG(ERROR, TAG, "OCEncodeAddressForRFC6874 failed: encoded output will not fit!");
return OC_STACK_ERROR;
}
return OC_STACK_OK;
}
+OCStackResult OCDecodeAddressForRFC6874(char *outputAddress,
+ size_t outputSize,
+ const char *inputAddress,
+ const char *end)
+{
+ VERIFY_NON_NULL(inputAddress, FATAL, OC_STACK_INVALID_PARAM);
+ VERIFY_NON_NULL(outputAddress, FATAL, OC_STACK_INVALID_PARAM);
+
+ if (NULL == end)
+ {
+ end = inputAddress + strlen(inputAddress);
+ }
+ size_t inputLength = end - inputAddress;
+
+ const char *percent = strchr(inputAddress, '%');
+ if (!percent || (percent > end))
+ {
+ OICStrcpyPartial(outputAddress, outputSize, inputAddress, inputLength);
+ }
+ else
+ {
+ if (percent[1] != '2' || percent[2] != '5')
+ {
+ return OC_STACK_INVALID_URI;
+ }
+
+ int addrlen = percent - inputAddress + 1;
+ OICStrcpyPartial(outputAddress, outputSize, inputAddress, addrlen);
+ OICStrcpyPartial(outputAddress + addrlen, outputSize - addrlen,
+ percent + 3, end - percent - 3);
+ }
+
+ return OC_STACK_OK;
+}
+
/**
* The cononical presence allows constructed URIs to be string compared.
*
{
char addressEncoded[CA_MAX_URI_LENGTH] = {0};
- OCStackResult result = encodeAddressForRFC6874(addressEncoded,
- sizeof(addressEncoded),
- ep->addr);
+ OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
+ sizeof(addressEncoded),
+ ep->addr);
if (OC_STACK_OK != result)
{
#endif
else if (strcmp(cbNode->requestUri, OC_RSRVD_DEVICE_URI) == 0)
{
- type = PAYLOAD_TYPE_DEVICE;
+ type = PAYLOAD_TYPE_REPRESENTATION;
}
else if (strcmp(cbNode->requestUri, OC_RSRVD_PLATFORM_URI) == 0)
{
- type = PAYLOAD_TYPE_PLATFORM;
+ type = PAYLOAD_TYPE_REPRESENTATION;
}
+
#ifdef ROUTING_GATEWAY
else if (strcmp(cbNode->requestUri, OC_RSRVD_GATEWAY_URI) == 0)
{
#endif
else if (strcmp(cbNode->requestUri, OC_RSRVD_RD_URI) == 0)
{
- type = PAYLOAD_TYPE_REPRESENTATION ;
+ type = PAYLOAD_TYPE_REPRESENTATION;
}
#ifdef TCP_ADAPTER
else if (strcmp(cbNode->requestUri, KEEPALIVE_RESOURCE_URI) == 0)
{
if (cbNode->requestUri)
{
- if (strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri) == 0)
+ if (0 == strcmp(OC_RSRVD_PLATFORM_URI, cbNode->requestUri))
{
- type = PAYLOAD_TYPE_PLATFORM;
+ type = PAYLOAD_TYPE_REPRESENTATION;
}
- else if (strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri) == 0)
+ else if (0 == strcmp(OC_RSRVD_DEVICE_URI, cbNode->requestUri))
{
- type = PAYLOAD_TYPE_DEVICE;
+ type = PAYLOAD_TYPE_REPRESENTATION;
}
if (type == PAYLOAD_TYPE_INVALID)
{
}
else
{
+#ifdef RD_CLIENT
+ // if request uri is '/oic/rd', update ins value of resource.
+ char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI);
+ if (targetUri)
+ {
+ OCUpdateResourceInsWithResponse(cbNode->requestUri, &response);
+ }
+#endif
OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context,
cbNode->handle,
&response);
*/
void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
{
- OIC_LOG(INFO, TAG, "Enter HandleCAErrorResponse");
-
- if (NULL == endPoint)
- {
- OIC_LOG(ERROR, TAG, "endPoint is NULL");
- return;
- }
+ VERIFY_NON_NULL_NR(endPoint, FATAL);
+ VERIFY_NON_NULL_NR(errorInfo, FATAL);
- if (NULL == errorInfo)
- {
- OIC_LOG(ERROR, TAG, "errorInfo is NULL");
- return;
- }
+ OIC_LOG(INFO, TAG, "Enter HandleCAErrorResponse");
ClientCB *cbNode = GetClientCB(errorInfo->info.token,
errorInfo->info.tokenLength, NULL, NULL);
memcpy(response.identity.id, errorInfo->info.identity.id,
sizeof (response.identity.id));
response.identity.id_length = errorInfo->info.identity.id_length;
- response.result = CAResultToOCStackResult(errorInfo->result);
+ response.result = CAResultToOCResult(errorInfo->result);
cbNode->callBack(cbNode->context, cbNode->handle, &response);
}
+ ResourceObserver *observer = GetObserverUsingToken(errorInfo->info.token,
+ errorInfo->info.tokenLength);
+ if (observer)
+ {
+ OIC_LOG(INFO, TAG, "Receiving communication error for an observer");
+ OCStackResult result = CAResultToOCResult(errorInfo->result);
+ if (OC_STACK_COMM_ERROR == result)
+ {
+ OCStackFeedBack(errorInfo->info.token, errorInfo->info.tokenLength,
+ OC_OBSERVER_FAILED_COMM);
+ }
+ }
+
OIC_LOG(INFO, TAG, "Exit HandleCAErrorResponse");
}
if(OC_STACK_OK != result)
{
OIC_LOG_V(ERROR, TAG, "Add routing option failed [%d]", result);
+ OICFree (respInfo.info.resourceUri);
+ OICFree (respInfo.info.options);
return result;
}
if (doPost)
if (NULL == reqInfo.info.options)
{
OIC_LOG(ERROR, TAG, "Calloc failed");
+ OICFree (reqInfo.info.resourceUri);
+ OICFree (respInfo.info.resourceUri);
+ OICFree (respInfo.info.options);
return OC_STACK_NO_MEMORY;
}
memcpy (reqInfo.info.options, respInfo.info.options,
OIC_LOG(INFO, TAG, "Exit HandleCARequests");
}
-bool validatePlatformInfo(OCPlatformInfo info)
-{
-
- if (!info.platformID)
- {
- OIC_LOG(ERROR, TAG, "No platform ID found.");
- return false;
- }
-
- if (info.manufacturerName)
- {
- size_t lenManufacturerName = strlen(info.manufacturerName);
-
- if(lenManufacturerName == 0 || lenManufacturerName > MAX_MANUFACTURER_NAME_LENGTH)
- {
- OIC_LOG(ERROR, TAG, "Manufacturer name fails length requirements.");
- return false;
- }
- }
- else
- {
- OIC_LOG(ERROR, TAG, "No manufacturer name present");
- return false;
- }
-
- if (info.manufacturerUrl)
- {
- if(strlen(info.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
- {
- OIC_LOG(ERROR, TAG, "Manufacturer url fails length requirements.");
- return false;
- }
- }
- return true;
-}
-
//-----------------------------------------------------------------------------
// Public APIs
//-----------------------------------------------------------------------------
// Free memory dynamically allocated for resources
deleteAllResources();
- DeleteDeviceInfo();
- DeletePlatformInfo();
CATerminate();
TerminateScheduleResourceList();
// Remove all observers
{
return OC_STACK_NO_MEMORY;
}
- OICStrcpyPartial(da->addr, sizeof(da->addr), start, len);
+
+ // Decode address per RFC 6874.
+ result = OCDecodeAddressForRFC6874(da->addr, sizeof(da->addr), start, end);
+ if (result != OC_STACK_OK)
+ {
+ OICFree(*devAddr);
+ return result;
+ }
+
da->port = port;
da->adapter = adapter;
da->flags = flags;
#ifdef WITH_PRESENCE
if (method == OC_REST_PRESENCE)
{
- if (requestInfo.isMulticast)
- {
- OIC_LOG(ERROR, TAG, "AddClientCB for presence done.");
- goto exit;
- }
- else
+ OIC_LOG(ERROR, TAG, "AddClientCB for presence done.");
+
+ if (handle)
{
- OIC_LOG(ERROR, TAG, "this subscribe presence is unicast.");
+ *handle = resHandle;
}
+
+ goto exit;
}
#endif
return OC_STACK_OK;
}
-OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo)
-{
- OIC_LOG(INFO, TAG, "Entering OCSetPlatformInfo");
-
- if(myStackMode == OC_SERVER || myStackMode == OC_CLIENT_SERVER || myStackMode == OC_GATEWAY)
- {
- if (validatePlatformInfo(platformInfo))
- {
- return SavePlatformInfo(platformInfo);
- }
- else
- {
- return OC_STACK_INVALID_PARAM;
- }
- }
- else
- {
- return OC_STACK_ERROR;
- }
-}
-
-OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
-{
- OIC_LOG(INFO, TAG, "Entering OCSetDeviceInfo");
-
- if (!deviceInfo.deviceName || deviceInfo.deviceName[0] == '\0')
- {
- OIC_LOG(ERROR, TAG, "Null or empty device name.");
- return OC_STACK_INVALID_PARAM;
- }
-
- if (deviceInfo.types)
- {
- OCStringLL *type = deviceInfo.types;
- OCResource *resource = findResource((OCResource *) deviceResource);
- if (!resource)
- {
- return OC_STACK_INVALID_PARAM;
- }
-
- while (type)
- {
- OCBindResourceTypeToResource(deviceResource, type->value);
- type = type->next;
- }
- }
- return SaveDeviceInfo(deviceInfo);
-}
-
OCStackResult OCCreateResource(OCResourceHandle *handle,
const char *resourceTypeName,
const char *resourceInterfaceName,
// Normal response
// Get pointer to request info
- serverRequest = GetServerRequestUsingHandle((OCServerRequest *)ehResponse->requestHandle);
+ serverRequest = GetServerRequestUsingHandle(ehResponse->requestHandle);
if(serverRequest)
{
// response handler in ocserverrequest.c. Usually HandleSingleResponse.
OICFree(resource->uri);
deleteResourceType(resource->rsrcType);
deleteResourceInterface(resource->rsrcInterface);
+ OCDeleteResourceAttributes(resource->rsrcAttributes);
}
void deleteResourceType(OCResourceType *resourceType)
}
}
+void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes)
+{
+ OCAttribute *next = NULL;
+ for (OCAttribute *pointer = rsrcAttributes; pointer; pointer = next)
+ {
+ next = pointer->next;
+ if (pointer->attrName && 0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, pointer->attrName))
+ {
+ OCFreeOCStringLL((OCStringLL *)pointer->attrValue);
+ }
+ else
+ {
+ OICFree(pointer->attrValue);
+ }
+ OICFree(pointer->attrName);
+ OICFree(pointer);
+ }
+}
+
void insertResourceType(OCResource *resource, OCResourceType *resourceType)
{
OCResourceType *pointer = NULL;
static bool generated = false;
static char sidStr[UUID_STRING_SIZE];
- if(generated)
+ if (generated)
{
return sidStr;
}
const OicUuid_t *sid = OCGetServerInstanceID();
- if(OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK)
+ if (sid && OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK)
{
OIC_LOG(FATAL, TAG, "Generate UUID String for Server Instance failed!");
return NULL;
return OC_STACK_OK;
}
+
+OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri,
+ const OCClientResponse *response)
+{
+ // Validate input parameters
+ VERIFY_NON_NULL(requestUri, ERROR, OC_STACK_INVALID_PARAM);
+ VERIFY_NON_NULL(response, ERROR, OC_STACK_INVALID_PARAM);
+
+ char *targetUri = (char *) OICMalloc(strlen(requestUri) + 1);
+ if (!targetUri)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ strncpy(targetUri, requestUri, strlen(requestUri) + 1);
+
+ if (response->result == OC_STACK_RESOURCE_CHANGED) // publish message
+ {
+ OIC_LOG(DEBUG, TAG, "update the ins of published resource");
+
+ char rdPubUri[MAX_URI_LENGTH] = { 0 };
+ snprintf(rdPubUri, MAX_URI_LENGTH, "%s?rt=%s", OC_RSRVD_RD_URI,
+ OC_RSRVD_RESOURCE_TYPE_RDPUBLISH);
+
+ if (strcmp(rdPubUri, targetUri) == 0)
+ {
+ // Update resource unique id in stack.
+ if (response)
+ {
+ if (response->payload)
+ {
+ OCRepPayload *rdPayload = (OCRepPayload *) response->payload;
+ OCRepPayload **links = NULL;
+ size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+ if (OCRepPayloadGetPropObjectArray(rdPayload, OC_RSRVD_LINKS,
+ &links, dimensions))
+ {
+ size_t i = 0;
+ for (; i < dimensions[0]; i++)
+ {
+ char *uri = NULL;
+ if (OCRepPayloadGetPropString(links[i], OC_RSRVD_HREF, &uri))
+ {
+ OCResourceHandle handle = OCGetResourceHandleAtUri(uri);
+ int64_t ins = 0;
+ if (OCRepPayloadGetPropInt(links[i], OC_RSRVD_INS, &ins))
+ {
+ OCBindResourceInsToResource(handle, ins);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (response->result == OC_STACK_RESOURCE_DELETED) // delete message
+ {
+ OIC_LOG(DEBUG, TAG, "update the ins of deleted resource with 0");
+
+ uint8_t numResources = 0;
+ OCGetNumberOfResources(&numResources);
+
+ char *ins = strstr(targetUri, OC_RSRVD_INS);
+ if (!ins)
+ {
+ for (uint8_t i = 0; i < numResources; i++)
+ {
+ OCResourceHandle resHandle = OCGetResourceHandle(i);
+ if (resHandle)
+ {
+ OCBindResourceInsToResource(resHandle, 0);
+ }
+ }
+ }
+ else
+ {
+ const char *token = "&";
+ char *iterTokenPtr = NULL;
+ char *start = strtok_r(targetUri, token, &iterTokenPtr);
+
+ while (start != NULL)
+ {
+ char *query = start;
+ query = strstr(query, OC_RSRVD_INS);
+ if (query)
+ {
+ uint8_t queryIns = atoi(query + 4);
+ for (uint8_t i = 0; i < numResources; i++)
+ {
+ OCResourceHandle resHandle = OCGetResourceHandle(i);
+ if (resHandle)
+ {
+ uint8_t resIns = 0;
+ OCGetResourceIns(resHandle, &resIns);
+ if (queryIns && queryIns == resIns)
+ {
+ OCBindResourceInsToResource(resHandle, 0);
+ break;
+ }
+ }
+ }
+ }
+ start = strtok_r(NULL, token, &iterTokenPtr);
+ }
+ }
+ }
+
+ OICFree(targetUri);
+ return OC_STACK_OK;
+}
+
OCResourceHandle OCGetResourceHandleAtUri(const char *uri)
{
if (!uri)
}
return OC_STACK_ERROR;
}
+#endif
OCStackResult OCSetHeaderOption(OCHeaderOption* ocHdrOpt, size_t* numOptions, uint16_t optionID,
- void* optionData, size_t optionDataLength)
+ void* optionData, size_t optionDataLength)
{
if (!ocHdrOpt)
{
return OC_STACK_OK;
}
+
OCStackResult OCGetHeaderOption(OCHeaderOption* ocHdrOpt, size_t numOptions, uint16_t optionID,
- void* optionData, size_t optionDataLength, uint16_t* receivedDataLength)
+ void* optionData, size_t optionDataLength, uint16_t* receivedDataLength)
{
if (!ocHdrOpt || !numOptions)
{
}
return OC_STACK_OK;
}
-#endif
void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
{
OCStackResult OCGetDeviceId(OCUUIdentity *deviceId)
{
OicUuid_t oicUuid;
- OCStackResult ret;
+ OCStackResult ret = OC_STACK_ERROR;
ret = GetDoxmDeviceID(&oicUuid);
if (OC_STACK_OK == ret)
OCStackResult OCSetDeviceId(const OCUUIdentity *deviceId)
{
OicUuid_t oicUuid;
- OCStackResult ret;
- OIC_LOG(ERROR, TAG, "Set deviceId DOXM");
+ OCStackResult ret = OC_STACK_ERROR;
memcpy(&oicUuid, deviceId, UUID_LENGTH);
- for(int i=0;i < UUID_LENGTH; i++)
+ for (int i = 0; i < UUID_LENGTH; i++)
{
OIC_LOG_V(INFO, TAG, "Set Device Id %x", oicUuid.id[i]);
}