// Discovery Links Map Length.
#define LINKS_MAP_LEN 4
+// Default data model versions in CVS form
+#define DEFAULT_DATA_MODEL_VERSIONS "res.1.1.0,sh.1.1.0"
+
// Functions all return either a CborError, or a negative version of the OC_STACK return values
static int64_t OCConvertPayloadHelper(OCPayload *payload, uint8_t *outPayload, size_t *size);
static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *outPayload,
// TinyCbor Version 47a78569c0 or better on master is required for the re-allocation
// strategy to work. If you receive the following assertion error, please do a git-pull
// from the extlibs/tinycbor/tinycbor directory
- #define CborNeedsUpdating (CborErrorOutOfMemory < CborErrorDataTooLarge)
+ #define CborNeedsUpdating (((unsigned int)CborErrorOutOfMemory) < ((unsigned int)CborErrorDataTooLarge))
OC_STATIC_ASSERT(!CborNeedsUpdating, "tinycbor needs to be updated to at least 47a78569c0");
#undef CborNeedsUpdating
VERIFY_PARAM_NON_NULL(TAG, size, "size parameter is NULL");
OIC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type);
-
- out = (uint8_t *)OICCalloc(1, curSize);
- VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload");
+ if (PAYLOAD_TYPE_SECURITY == payload->type)
+ {
+ size_t securityPayloadSize = ((OCSecurityPayload *)payload)->payloadSize;
+ if (securityPayloadSize > 0)
+ {
+ out = (uint8_t *)OICCalloc(1, ((OCSecurityPayload *)payload)->payloadSize);
+ VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate security payload");
+ }
+ }
+ if (out == NULL)
+ {
+ out = (uint8_t *)OICCalloc(1, curSize);
+ VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload");
+ }
err = OCConvertPayloadHelper(payload, out, &curSize);
ret = OC_STACK_NO_MEMORY;
if (err == CborNoError)
{
- if (curSize < INIT_SIZE)
+ if (curSize < INIT_SIZE && PAYLOAD_TYPE_SECURITY != payload->type)
{
uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
*size = curSize;
*outPayload = out;
- OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : %s \n", *size, *outPayload);
+ OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : ", *size);
+ OIC_LOG_BUFFER(DEBUG, TAG, *outPayload, *size);
return OC_STACK_OK;
}
static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* outPayload,
size_t* size)
{
- CborEncoder encoder;
- cbor_encoder_init(&encoder, outPayload, *size, 0);
-
- CborEncoder map;
- int64_t err = cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
- VERIFY_CBOR_SUCCESS(TAG, err, "Creating security map");
-
- if (payload->securityData)
- {
- err |= cbor_encode_text_string(&map, payload->securityData,
- strlen(payload->securityData));
- VERIFY_CBOR_SUCCESS(TAG, err, "Retrieving security data");
- }
+ memcpy(outPayload, payload->securityData, payload->payloadSize);
+ *size = payload->payloadSize;
- err |= cbor_encoder_close_container(&encoder, &map);
- VERIFY_CBOR_SUCCESS(TAG, err, "closing security map");
-exit:
- return checkError(err, &encoder, outPayload, size);
+ return CborNoError;
}
-static char* OCStringLLJoin(OCStringLL* val)
+static int64_t OCStringLLJoin(CborEncoder *map, char *type, OCStringLL *val)
{
- OCStringLL* temp = val;
- size_t size = strlen(temp->value);
+ uint16_t count = 0;
+ int64_t err = CborNoError;
- while (temp->next)
+ for (OCStringLL *temp = val; temp; temp = temp->next)
{
- ++size;
- temp = temp->next;
- size += strlen(temp->value);
+ ++count;
}
-
- char* joinedStr = (char*)OICCalloc(sizeof(char), size + 1);
-
- if (!joinedStr)
+ if (count > 0)
{
- return NULL;
+ CborEncoder array;
+ err |= cbor_encode_text_string(map, type, strlen(type));
+ err |= cbor_encoder_create_array(map, &array, count);
+ while (val)
+ {
+ err |= cbor_encode_text_string(&array, val->value, strlen(val->value));
+ val = val->next;
+ }
+ err |= cbor_encoder_close_container(map, &array);
}
- OICStrcat(joinedStr, size + 1, val->value);
- while (val->next)
- {
- val = val->next;
- OICStrcat(joinedStr, size + 1, " ");
- OICStrcat(joinedStr, size + 1, val->value);
- }
- return joinedStr;
+ return err;
}
static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *outPayload,
- size_t *size)
+ size_t *size)
{
CborEncoder encoder;
int64_t err = CborNoError;
cbor_encoder_init(&encoder, outPayload, *size, 0);
- if (payload->resources)
- {
- /*
- The format for the payload is "modelled" as JSON.
-
- [ // rootArray
- { // rootMap
- "di" : UUID, // device ID
- "href": "/oic/res"
- "rt": "oic.wk.res"
- "n":"MyDevice"
- "if":"oic.if.ll oic.if.baseline"
- "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1",
- links :[ // linksArray contains maps of resources
- {
- href, rt, if, policy // Resource 1
- },
- {
- href, rt, if, policy // Resource 2
- },
- .
- .
- .
- ]
- }
- ]
- */
- // Open the main root array
- CborEncoder rootArray;
- size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload);
- err |= cbor_encoder_create_array(&encoder, &rootArray, 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array");
+ /*
+ The format for the payload is "modelled" as JSON.
+
+ [ // rootArray
+ { // rootMap
+ "di" : UUID, // device ID
+ "rt": ["oic.wk.res"]
+ "n":"MyDevice"
+ "if":"oic.if.ll oic.if.baseline"
+ "di": "0685B960-736F-46F7-BEC0-9E6CBD61ADC1",
+ links :[ // linksArray contains maps of resources
+ {
+ href, rt, if, policy // Resource 1
+ },
+ {
+ href, rt, if, policy // Resource 2
+ },
+ .
+ .
+ .
+ ]
+ }
+ { // rootMap
+ ...
+ }
+ ]
+ */
+ // Open the main root array
+ CborEncoder rootArray;
+ err |= cbor_encoder_create_array(&encoder, &rootArray, 1);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed creating discovery root array");
+
+ while (payload && payload->resources)
+ {
// Open the root map in the root array
CborEncoder rootMap;
err |= cbor_encoder_create_map(&rootArray, &rootMap, CborIndefiniteLength);
sizeof(OC_RSRVD_DEVICE_NAME) - 1, payload->name);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting name");
- // Insert URI
- err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_HREF, sizeof(OC_RSRVD_HREF) - 1,
- payload->uri);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting href");
-
// Insert Device ID into the root map
err |= AddTextStringToMap(&rootMap, OC_RSRVD_DEVICE_ID, sizeof(OC_RSRVD_DEVICE_ID) - 1,
payload->sid);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting device id");
// Insert Resource Type
- err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_RESOURCE_TYPE,
- sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->type);
+ err |= OCStringLLJoin(&rootMap, OC_RSRVD_RESOURCE_TYPE, payload->type);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting RT");
// Insert interfaces
- if (payload->interface)
+ if (payload->iface)
{
- err |= cbor_encode_text_string(&rootMap, OC_RSRVD_INTERFACE,
- sizeof(OC_RSRVD_INTERFACE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types tag");
- char *joinedTypes = OCStringLLJoin(payload->interface);
- VERIFY_PARAM_NON_NULL(TAG, joinedTypes, "Failed creating joined string");
- err |= cbor_encode_text_string(&rootMap, joinedTypes, strlen(joinedTypes));
- OICFree(joinedTypes);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types value");
+ err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->iface);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface types tag/value");
}
// Insert baseURI if present
err |= ConditionalAddTextStringToMap(&rootMap, OC_RSRVD_BASE_URI,
- sizeof(OC_RSRVD_BASE_URI) - 1,
- payload->baseURI);
+ sizeof(OC_RSRVD_BASE_URI) - 1,
+ payload->baseURI);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting baseURI");
// Insert Links into the root map.
CborEncoder linkArray;
err |= cbor_encode_text_string(&rootMap, OC_RSRVD_LINKS, sizeof(OC_RSRVD_LINKS) - 1);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array tag");
+ size_t resourceCount = OCDiscoveryPayloadGetResourceCount(payload);
err |= cbor_encoder_create_array(&rootMap, &linkArray, resourceCount);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed setting links array");
- for(size_t i = 0; i < resourceCount; ++i)
+ for (size_t i = 0; i < resourceCount; ++i)
{
CborEncoder linkMap;
OCResourcePayload *resource = OCDiscoveryPayloadGetResource(payload, i);
// Resource Type
if (resource->types)
{
- err |= cbor_encode_text_string(&linkMap, OC_RSRVD_RESOURCE_TYPE,
- sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource types tag to links map");
- char *joinedTypes = OCStringLLJoin(resource->types);
- VERIFY_PARAM_NON_NULL(TAG, joinedTypes, "Failed creating joined string");
- err |= cbor_encode_text_string(&linkMap, joinedTypes, strlen(joinedTypes));
- OICFree(joinedTypes);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource types value to links map");
+ err |= OCStringLLJoin(&linkMap, OC_RSRVD_RESOURCE_TYPE, resource->types);
+ VERIFY_CBOR_SUCCESS(TAG, err,
+ "Failed adding resourceType tag/value to links map");
}
// Interface Types
if (resource->interfaces)
{
- err |= cbor_encode_text_string(&linkMap, OC_RSRVD_INTERFACE,
- sizeof(OC_RSRVD_INTERFACE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interfaces tag to links map");
- char* joinedInterfaces = OCStringLLJoin(resource->interfaces);
- VERIFY_PARAM_NON_NULL(TAG, joinedInterfaces, "Failed creating joined string");
- err |= cbor_encode_text_string(&linkMap, joinedInterfaces, strlen(joinedInterfaces));
- OICFree(joinedInterfaces);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interfaces value to links map");
+ err |= OCStringLLJoin(&linkMap, OC_RSRVD_INTERFACE, resource->interfaces);
+ VERIFY_CBOR_SUCCESS(TAG, err,
+ "Failed adding interfaces tag/value to links map");
}
// Policy
CborEncoder policyMap;
- err |= cbor_encode_text_string(&linkMap, OC_RSRVD_POLICY, sizeof(OC_RSRVD_POLICY) - 1);
+ err |= cbor_encode_text_string(&linkMap, OC_RSRVD_POLICY,
+ sizeof(OC_RSRVD_POLICY) - 1);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy tag to links map");
err |= cbor_encoder_create_map(&linkMap, &policyMap, CborIndefiniteLength);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding policy map to links map");
// Bitmap
- err |= cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP, sizeof(OC_RSRVD_BITMAP) - 1);
+ err |= cbor_encode_text_string(&policyMap, OC_RSRVD_BITMAP,
+ sizeof(OC_RSRVD_BITMAP) - 1);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap tag to policy map");
err |= cbor_encode_uint(&policyMap, resource->bitmap);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding bitmap value to policy map");
- if (resource->secure)
- {
- err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
- sizeof(OC_RSRVD_SECURE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map");
- err |= cbor_encode_boolean(&policyMap, OC_RESOURCE_SECURE);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map");
- }
- if ((resource->secure && resource->port != 0) || payload->baseURI)
+ // Secure
+ err |= cbor_encode_text_string(&policyMap, OC_RSRVD_SECURE,
+ sizeof(OC_RSRVD_SECURE) - 1);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure tag to policy map");
+ err |= cbor_encode_boolean(&policyMap, resource->secure);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure value to policy map");
+
+ if (resource->secure || payload->baseURI)
{
err |= cbor_encode_text_string(&policyMap, OC_RSRVD_HOSTING_PORT,
- sizeof(OC_RSRVD_HOSTING_PORT) - 1);
+ sizeof(OC_RSRVD_HOSTING_PORT) - 1);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port tag");
err |= cbor_encode_uint(&policyMap, resource->port);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port value");
}
+#ifdef TCP_ADAPTER
+ err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TCP_PORT,
+ sizeof(OC_RSRVD_TCP_PORT) - 1);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port tag");
+ err |= cbor_encode_uint(&policyMap, resource->tcpPort);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port value");
+#endif
+
err |= cbor_encoder_close_container(&linkMap, &policyMap);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing policy map");
// close root map inside the root array.
err |= cbor_encoder_close_container(&rootArray, &rootMap);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root map");
- // Close the final root array.
- err |= cbor_encoder_close_container(&encoder, &rootArray);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array");
+
+ payload = payload->next;
}
+ // Close the final root array.
+ err |= cbor_encoder_close_container(&encoder, &rootArray);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing root array");
+
exit:
return checkError(err, &encoder, outPayload, size);
}
}
int64_t err = CborNoError;
CborEncoder encoder;
+ char *dataModelVersions = 0;
cbor_encoder_init(&encoder, outPayload, *size, 0);
CborEncoder repMap;
if (payload->types)
{
OIC_LOG(INFO, TAG, "Payload has types");
- err |= cbor_encode_text_string(&repMap, OC_RSRVD_RESOURCE_TYPE,
- sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep resource type tag");
- char *joinedTypes = OCStringLLJoin(payload->types);
- VERIFY_PARAM_NON_NULL(TAG, joinedTypes, "Failed creating joined string");
- err |= cbor_encode_text_string(&repMap, joinedTypes, strlen(joinedTypes));
- OICFree(joinedTypes);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep resource type value");
+ err |= OCStringLLJoin(&repMap, OC_RSRVD_RESOURCE_TYPE, payload->types);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource type tag/value.");
}
if (payload->interfaces)
{
OIC_LOG(INFO, TAG, "Payload has interface");
- err |= cbor_encode_text_string(&repMap, OC_RSRVD_INTERFACE,
- sizeof(OC_RSRVD_INTERFACE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface type tag");
- char *joinedTypes = OCStringLLJoin(payload->interfaces);
- VERIFY_PARAM_NON_NULL(TAG, joinedTypes, "Failed creating joined string");
- err |= cbor_encode_text_string(&repMap, joinedTypes, strlen(joinedTypes));
- OICFree(joinedTypes);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep resource type value");
+ err |= OCStringLLJoin(&repMap, OC_RSRVD_INTERFACE, payload->interfaces);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding interface type tag/value.");
}
// Device ID
sizeof(OC_RSRVD_SPEC_VERSION) - 1, payload->specVersion);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding data spec version");
- // Device data Model Version
+ // Device data Model Versions
+ if (payload->dataModelVersions)
+ {
+ OIC_LOG(INFO, TAG, "Payload has data model versions");
+ dataModelVersions = OCCreateString(payload->dataModelVersions);
+ }
+ else
+ {
+ dataModelVersions = OICStrdup(DEFAULT_DATA_MODEL_VERSIONS);
+ }
err |= ConditionalAddTextStringToMap(&repMap, OC_RSRVD_DATA_MODEL_VERSION,
- sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1, payload->dataModelVersion);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding data model version");
+ sizeof(OC_RSRVD_DATA_MODEL_VERSION) - 1, dataModelVersions);
+ OICFree(dataModelVersions);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding data model versions");
err |= cbor_encoder_close_container(&encoder, &repMap);
VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing device map");
// Resource type
if (payload->rt)
{
- err |= ConditionalAddTextStringToMap(&repMap, OC_RSRVD_RESOURCE_TYPE,
- sizeof(OC_RSRVD_RESOURCE_TYPE) - 1, payload->rt);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource type");
+ err |= OCStringLLJoin(&repMap, OC_RSRVD_RESOURCE_TYPE, payload->rt);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource type.");
}
// Resource interfaces
if (payload->interfaces)
{
- err |= cbor_encode_text_string(&repMap, OC_RSRVD_INTERFACE,
- sizeof(OC_RSRVD_INTERFACE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding platform interface tag");
- char* joinedInterfaces = OCStringLLJoin(payload->interfaces);
- VERIFY_PARAM_NON_NULL(TAG, joinedInterfaces, "Failed creating joined string");
- err |= cbor_encode_text_string(&repMap, joinedInterfaces, strlen(joinedInterfaces));
- OICFree(joinedInterfaces);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding platform interface value");
+ err |= OCStringLLJoin(&repMap, OC_RSRVD_INTERFACE, payload->interfaces);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding platform interface type.");
}
// Close Map
if (payload->types)
{
OIC_LOG(INFO, TAG, "Payload has types");
- err |= cbor_encode_text_string(&rootMap, OC_RSRVD_RESOURCE_TYPE,
- sizeof(OC_RSRVD_RESOURCE_TYPE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep resource type tag");
- char* joinedTypes = OCStringLLJoin(payload->types);
- VERIFY_PARAM_NON_NULL(TAG, joinedTypes, "Failed creating joined string");
- err |= cbor_encode_text_string(&rootMap, joinedTypes, strlen(joinedTypes));
- OICFree(joinedTypes);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep resource type value");
+ err |= OCStringLLJoin(&rootMap, OC_RSRVD_RESOURCE_TYPE, payload->types);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding resource type.");
}
if (payload->interfaces)
{
OIC_LOG(INFO, TAG, "Payload has interfaces");
- err |= cbor_encode_text_string(&rootMap, OC_RSRVD_INTERFACE,
- sizeof(OC_RSRVD_INTERFACE) - 1);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep interface tag");
- char* joinedInterfaces = OCStringLLJoin(payload->interfaces);
- VERIFY_PARAM_NON_NULL(TAG, joinedInterfaces, "Failed creating joined string");
- err |= cbor_encode_text_string(&rootMap, joinedInterfaces, strlen(joinedInterfaces));
- OICFree(joinedInterfaces);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding rep interface value");
+ err |= OCStringLLJoin(&rootMap, OC_RSRVD_INTERFACE, payload->interfaces);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding platform interface type.");
}
err |= OCConvertSingleRepPayload(&rootMap, payload);