Commit e01bcc8d authored by Mandeep Shetty's avatar Mandeep Shetty Committed by Erich Keane

Spec compliance change to move oc/core/d to oic/p.

Moved /oc/core/d to /oic/p.
 -Created a  new struct for platform information.
 -Added code paths so devices can respond to platform discovery query.
 -Added public APIs to registerPlatform used by server devices and
  getPlatformInfo used by client devices. getPlatformInfo is just to make
  the intent of the request clear. Internally, it uses all of the plumbing
  that is already in place for what was previously "device".
 -Changed stack to hold smaller OCPlatfromInfo object compared to a
  cJson object. Construct cjson only when discovery request received and
  delete immediately.

Change-Id: Ie5cca447e8fac67171be5a5ec7c5ece563fbb7ca
Signed-off-by: default avatarMandeep Shetty <mandeep.shetty@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/987Tested-by: default avatarjenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: default avatarErich Keane <erich.keane@intel.com>
parent 8d1dc74b
......@@ -110,10 +110,15 @@ OCStackResult ProcessRequest(ResourceHandling resHandling,
OCServerRequest *request);
/**
* Internal API used to save all of the device's information for use in device
* Internal API used to save all of the platform's information for use in platform
* discovery requests.
*/
OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo);
OCStackResult SavePlatformInfo(OCPlatformInfo info);
/**
* Internal API used to clear the platform information.
*/
void DeletePlatformInfo();
/**
* Internal API used to clear the device information.
......
......@@ -177,6 +177,20 @@ OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandle
*/
OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo);
/**
* Set platform information.
*
* @param platformInfo - Structure passed by the server application containing
* the platform information.
*
*
* @return
* OC_STACK_OK - no errors
* OC_STACK_INVALID_PARAM - invalid paramerter
* OC_STACK_ERROR - stack process error
*/
OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo);
/**
* Create a resource.
*
......
......@@ -52,7 +52,7 @@ extern "C" {
/// operation.
#define OC_MAX_PRESENCE_TTL_SECONDS (60 * 60 * 24) // 60 sec/min * 60 min/hr * 24 hr/day
#define OC_PRESENCE_URI "/oic/ad"
#endif
/**
* Attributes used to form a proper OIC conforming JSON message.
*/
......@@ -71,20 +71,27 @@ extern "C" {
#define OC_RSRVD_INTERFACE_LL "oic.if.ll"
#define OC_RSRVD_INTERFACE_BATCH "oic.if.b"
#define OC_RSRVD_INTERFACE_GROUP "oc.mi.grp"
#define OC_RSRVD_MFG_DATE "mndt"
#define OC_RSRVD_FW_VERSION "mnfv"
#define OC_RSRVD_HOST_NAME "hn"
#define OC_RSRVD_MFG_NAME "mnmn"
#define OC_RSRVD_MFG_URL "mnml"
#define OC_RSRVD_MODEL_NUM "mnmo"
#define OC_RSRVD_PLATFORM_VERSION "mnpv"
#define OC_RSRVD_SUPPORT_URL "mnsl"
#define OC_RSRVD_VERSION "icv"
#define OC_RSRVD_OBSERVABLE "obs"
#define OC_RSRVD_SECURE "sec"
#define OC_RSRVD_HOSTING_PORT "port"
#define OC_RSRVD_SERVER_INSTANCE_ID "sid"
#endif
//**** Platform ****
#define OC_RSRVD_PLATFORM_ID "pi"
#define OC_RSRVD_MFG_NAME "mnmn"
#define OC_RSRVD_MFG_URL "mnml"
#define OC_RSRVD_MODEL_NUM "mnmo"
#define OC_RSRVD_MFG_DATE "mndt"
#define OC_RSRVD_PLATFORM_VERSION "mnpv"
#define OC_RSRVD_OS_VERSION "mnos"
#define OC_RSRVD_HARDWARE_VERSION "mnhw"
#define OC_RSRVD_FIRMWARE_VERSION "mnfv"
#define OC_RSRVD_SUPPORT_URL "mnsl"
#define OC_RSRVD_SYSTEM_TIME "st"
//*******************
//-----------------------------------------------------------------------------
// Typedefs
......@@ -106,6 +113,7 @@ typedef enum
{
OC_WELL_KNOWN_URI= 0, ///< "/oc/core"
OC_DEVICE_URI, ///< "/oc/core/d"
OC_PLATFORM_URI, ///< "/oic/p"
OC_RESOURCE_TYPES_URI, ///< "/oc/core/d/type"
#ifdef WITH_PRESENCE
OC_PRESENCE, ///< "/oic/ad"
......@@ -371,8 +379,27 @@ typedef struct
} OCClientResponse;
/**
* This structure describes the device properties. All non-Null properties will be included
* in a device discovery request.
* This structure describes the platform properties. All non-Null properties will be included
* in a platform discovery request.
*/
typedef struct
{
char *platformID;
char *manufacturerName;
char *manufacturerUrl;
char *modelNumber;
char *dateOfManufacture;
char *platformVersion;
char *operatingSystemVersion;
char *hardwareVersion;
char *firmwareVersion;
char *supportUrl;
char *systemTime;
} OCPlatformInfo;
/**
* TODO : Modify these. This is just so sample apps compile.
*/
typedef struct
{
......
......@@ -47,12 +47,13 @@
TAG, PCF(#arg " is NULL")); return (retVal); } }
extern OCResource *headResource;
static OCPlatformInfo savedPlatformInfo = {};
static cJSON *savedDeviceInfo = NULL;
static const char * VIRTUAL_RSRCS[] =
{
"/oc/core",
"/oc/core/d",
"/oic/p",
"/oc/core/types/d",
#ifdef WITH_PRESENCE
"/oic/ad"
......@@ -100,6 +101,86 @@ static OCStackResult GetSecurePortInfo(CATransportType_t connType, uint16_t *por
return ret;
}
static char* GetJSONStringFromPlatformInfo(OCPlatformInfo info)
{
cJSON *rootObj = cJSON_CreateObject();
if (!rootObj)
{
return NULL;
}
cJSON *repObj = NULL;
char *jsonEncodedInfo = NULL;
cJSON_AddItemToObject (rootObj, OC_RSRVD_HREF,
cJSON_CreateString(GetVirtualResourceUri(OC_PLATFORM_URI)));
cJSON_AddItemToObject (rootObj, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_ID, cJSON_CreateString(info.platformID));
cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME, cJSON_CreateString(info.manufacturerName));
if (info.manufacturerUrl)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
cJSON_CreateString(info.manufacturerUrl));
}
if (info.modelNumber)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
cJSON_CreateString(info.modelNumber));
}
if (info.dateOfManufacture)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
cJSON_CreateString(info.dateOfManufacture));
}
if (info.platformVersion)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
cJSON_CreateString(info.platformVersion));
}
if (info.operatingSystemVersion)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_OS_VERSION,
cJSON_CreateString(info.operatingSystemVersion));
}
if (info.hardwareVersion)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_HARDWARE_VERSION,
cJSON_CreateString(info.hardwareVersion));
}
if (info.firmwareVersion)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_FIRMWARE_VERSION,
cJSON_CreateString(info.firmwareVersion));
}
if (info.supportUrl)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
cJSON_CreateString(info.supportUrl));
}
if (info.systemTime)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_SYSTEM_TIME,
cJSON_CreateString(info.systemTime));
}
jsonEncodedInfo = cJSON_PrintUnformatted (rootObj);
cJSON_Delete(rootObj);
return jsonEncodedInfo;
}
static OCStackResult ValidateUrlQuery (char *url, char *query,
uint8_t *filterOn, char **filterValue)
{
......@@ -117,7 +198,8 @@ static OCStackResult ValidateUrlQuery (char *url, char *query,
}
if (strcmp ((char *)url, GetVirtualResourceUri(OC_WELL_KNOWN_URI)) == 0 ||
strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0)
strcmp ((char *)url, GetVirtualResourceUri(OC_DEVICE_URI)) == 0 ||
strcmp((char *)url, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
{
*filterOn = STACK_RES_DISCOVERY_NOFILTER;
if (query && *query)
......@@ -389,6 +471,7 @@ OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filt
}
else
{
OC_LOG(ERROR, TAG, PCF("No device info found."));
//error so that stack won't respond with empty payload
ret = OC_STACK_INVALID_DEVICE_INFO;
}
......@@ -397,6 +480,39 @@ OCStackResult BuildVirtualResourceResponseForDevice(uint8_t filterOn, char *filt
return ret;
}
OCStackResult BuildVirtualResourceResponseForPlatform(char *out, uint16_t *remaining)
{
OCStackResult ret = OC_STACK_OK;
char *jsonStr = GetJSONStringFromPlatformInfo(savedPlatformInfo);
if(jsonStr)
{
size_t jsonLen = strlen(jsonStr);
if (jsonLen < *remaining)
{
strncpy(out, jsonStr, (jsonLen + 1));
*remaining = *remaining - jsonLen;
ret = OC_STACK_OK;
}
else
{
OC_LOG_V(ERROR, TAG, PCF("Platform info string too big. len: %u"), jsonLen);
ret = OC_STACK_ERROR;
}
OCFree(jsonStr);
}
else
{
OC_LOG(ERROR, TAG, PCF("Error encoding save platform info."));
ret = OC_STACK_ERROR;
}
return ret;
}
const char * GetVirtualResourceUri( OCVirtualResources resource)
{
if (resource < OC_MAX_VIRTUAL_RESOURCES)
......@@ -683,6 +799,32 @@ HandleVirtualResource (OCServerRequest *request, OCResource* resource)
result = OCDoResponse(&response);
}
}
else if (strcmp ((char *)request->resourceUrl, GetVirtualResourceUri(OC_PLATFORM_URI)) == 0)
{
remaining = MAX_RESPONSE_LENGTH;
ptr = discoveryResBuf;
result = BuildVirtualResourceResponseForPlatform((char*)ptr, &remaining);
if(result == OC_STACK_OK)
{
ptr += strlen((char*)ptr);
}
if(remaining < MAX_RESPONSE_LENGTH)
{
OCEntityHandlerResponse response = {0};
response.ehResult = OC_EH_OK;
response.payload = discoveryResBuf;
response.payloadSize = strlen((const char *)discoveryResBuf) + 1;
response.persistentBufferFlag = 0;
response.requestHandle = (OCRequestHandle) request;
response.resourceHandle = (OCResourceHandle) resource;
result = OCDoResponse(&response);
}
}
#ifdef WITH_PRESENCE
else
{
......@@ -930,101 +1072,119 @@ void DeleteDeviceInfo()
}
}
OCStackResult SaveDeviceInfo(OCDeviceInfo deviceInfo)
void DeletePlatformInfo()
{
DeleteDeviceInfo();
OC_LOG(INFO, TAG, PCF("Deleting platform info."));
savedDeviceInfo = cJSON_CreateObject();
cJSON *repObj = NULL;
OCFree(savedPlatformInfo.platformID);
savedPlatformInfo.platformID = NULL;
cJSON_AddItemToObject (savedDeviceInfo, OC_RSRVD_HREF,
cJSON_CreateString(GetVirtualResourceUri(OC_DEVICE_URI)));
OCFree(savedPlatformInfo.manufacturerName);
savedPlatformInfo.manufacturerName = NULL;
cJSON_AddItemToObject (savedDeviceInfo, OC_RSRVD_REPRESENTATION, repObj = cJSON_CreateObject());
OCFree(savedPlatformInfo.manufacturerUrl);
savedPlatformInfo.manufacturerUrl = NULL;
if (deviceInfo.contentType)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_CONTENT_TYPE,
cJSON_CreateString(deviceInfo.contentType));
}
OCFree(savedPlatformInfo.modelNumber);
savedPlatformInfo.modelNumber = NULL;
if (deviceInfo.dateOfManufacture)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_DATE,
cJSON_CreateString(deviceInfo.dateOfManufacture));
}
OCFree(savedPlatformInfo.dateOfManufacture);
savedPlatformInfo.dateOfManufacture = NULL;
if (deviceInfo.deviceName)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_NAME,
cJSON_CreateString(deviceInfo.deviceName));
}
OCFree(savedPlatformInfo.platformVersion);
savedPlatformInfo.platformVersion = NULL;
if (deviceInfo.deviceUUID)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_DEVICE_ID,
cJSON_CreateString(deviceInfo.deviceUUID));
}
OCFree(savedPlatformInfo.operatingSystemVersion);
savedPlatformInfo.operatingSystemVersion = NULL;
if (deviceInfo.firmwareVersion)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_FW_VERSION,
cJSON_CreateString(deviceInfo.firmwareVersion));
}
OCFree(savedPlatformInfo.hardwareVersion);
savedPlatformInfo.hardwareVersion = NULL;
if (deviceInfo.hostName)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_HOST_NAME,
cJSON_CreateString(deviceInfo.hostName));
}
OCFree(savedPlatformInfo.firmwareVersion);
savedPlatformInfo.firmwareVersion = NULL;
if (deviceInfo.manufacturerName)
{
if(strlen(deviceInfo.manufacturerName) > MAX_MANUFACTURER_NAME_LENGTH)
{
DeleteDeviceInfo();
return OC_STACK_INVALID_PARAM;
}
OCFree(savedPlatformInfo.supportUrl);
savedPlatformInfo.supportUrl = NULL;
cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_NAME,
cJSON_CreateString(deviceInfo.manufacturerName));
}
OCFree(savedPlatformInfo.systemTime);
savedPlatformInfo.systemTime = NULL;
}
if (deviceInfo.manufacturerUrl)
static OCStackResult CloneStringIfNonNull(char **dest, char *src)
{
if (src)
{
if(strlen(deviceInfo.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
*dest = (char*) OCMalloc(strlen(src) + 1);
if (!*dest)
{
DeleteDeviceInfo();
return OC_STACK_INVALID_PARAM;
return OC_STACK_NO_MEMORY;
}
cJSON_AddItemToObject (repObj, OC_RSRVD_MFG_URL,
cJSON_CreateString(deviceInfo.manufacturerUrl));
strcpy(*dest, src);
}
if (deviceInfo.modelNumber)
else
{
cJSON_AddItemToObject (repObj, OC_RSRVD_MODEL_NUM,
cJSON_CreateString(deviceInfo.modelNumber));
*dest = NULL;
}
return OC_STACK_OK;
}
static OCStackResult DeepCopyPlatFormInfo(OCPlatformInfo info)
{
DeletePlatformInfo();
if (deviceInfo.platformVersion)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_PLATFORM_VERSION,
cJSON_CreateString(deviceInfo.platformVersion));
}
OCStackResult ret = OC_STACK_OK;
ret = CloneStringIfNonNull(&(savedPlatformInfo.platformID), info.platformID);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerName), info.manufacturerName);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.manufacturerUrl), info.manufacturerUrl);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.modelNumber), info.modelNumber);
VERIFY_SUCCESS(ret, OC_STACK_OK);
if (deviceInfo.supportUrl)
ret = CloneStringIfNonNull(&(savedPlatformInfo.dateOfManufacture), info.dateOfManufacture);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.platformVersion), info.platformVersion);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.operatingSystemVersion), info.operatingSystemVersion);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.hardwareVersion), info.hardwareVersion);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.firmwareVersion), info.firmwareVersion);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.supportUrl), info.supportUrl);
VERIFY_SUCCESS(ret, OC_STACK_OK);
ret = CloneStringIfNonNull(&(savedPlatformInfo.systemTime), info.systemTime);
VERIFY_SUCCESS(ret, OC_STACK_OK);
return OC_STACK_OK;
exit:
DeletePlatformInfo();
return ret;
}
OCStackResult SavePlatformInfo(OCPlatformInfo info)
{
OCStackResult res = DeepCopyPlatFormInfo(info);
if (res != OC_STACK_OK)
{
cJSON_AddItemToObject (repObj, OC_RSRVD_SUPPORT_URL,
cJSON_CreateString(deviceInfo.supportUrl));
OC_LOG_V(ERROR, TAG, PCF("Failed to save platform info. errno(%d)"), res);
}
if (deviceInfo.version)
else
{
cJSON_AddItemToObject (repObj, OC_RSRVD_VERSION,
cJSON_CreateString(deviceInfo.version));
OC_LOG(ERROR, TAG, PCF("Platform info saved."));
}
return OC_STACK_OK;
return res;
}
......@@ -1662,6 +1662,41 @@ bool ParseIPv4Address(char * ipAddrStr, uint8_t * ipAddr, uint16_t * port)
return (3 == dotCount);
}
bool validatePlatformInfo(OCPlatformInfo info)
{
if (!info.platformID)
{
OC_LOG(ERROR, TAG, PCF("No platform ID found."));
return false;
}
if (info.manufacturerName)
{
size_t lenManufacturerName = strlen(info.manufacturerName);
if(lenManufacturerName == 0 || lenManufacturerName > MAX_MANUFACTURER_NAME_LENGTH)
{
OC_LOG(ERROR, TAG, PCF("Manufacturer name fails length requirements."));
return false;
}
}
else
{
OC_LOG(ERROR, TAG, PCF("No manufacturer name present"));
return false;
}
if (info.manufacturerUrl)
{
if(strlen(info.manufacturerUrl) > MAX_MANUFACTURER_URL_LENGTH)
{
OC_LOG(ERROR, TAG, PCF("Manufacturer url fails length requirements."));
return false;
}
}
return true;
}
//-----------------------------------------------------------------------------
// Public APIs
//-----------------------------------------------------------------------------
......@@ -1774,6 +1809,7 @@ OCStackResult OCStop()
// Free memory dynamically allocated for resources
deleteAllResources();
DeleteDeviceInfo();
DeletePlatformInfo();
CATerminate();
// Remove all observers
DeleteObserverList();
......@@ -2426,13 +2462,20 @@ OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandle
return OC_STACK_OK;
}
OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo)
{
OC_LOG(INFO, TAG, PCF("Entering OCSetDeviceInfo"));
OC_LOG(INFO, TAG, PCF("Entering OCSetPlatformInfo"));
if(myStackMode == OC_SERVER || myStackMode == OC_CLIENT_SERVER)
{
return SaveDeviceInfo(deviceInfo);
if (validatePlatformInfo(platformInfo))
{
return SavePlatformInfo(platformInfo);
}
else
{
return OC_STACK_INVALID_PARAM;
}
}
else
{
......@@ -2440,6 +2483,15 @@ OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
}
}
OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo)
{
// TODO: Implement this.
OC_LOG(ERROR, TAG, "Implement OCSetDeviceInfo !!");
// Returning ok to make samples work.
return OC_STACK_OK;
}
OCStackResult OCCreateResource(OCResourceHandle *handle,
const char *resourceTypeName,
const char *resourceInterfaceName,
......
......@@ -54,6 +54,9 @@ namespace OC
virtual OCStackResult registerDeviceInfo(
const OCDeviceInfo deviceInfo) = 0;
virtual OCStackResult registerPlatformInfo(
const OCPlatformInfo PlatformInfo) = 0;
virtual OCStackResult registerResourceWithHost(
OCResourceHandle& resourceHandle,
std::string& resourceHOST,
......
......@@ -48,6 +48,9 @@ namespace OC
virtual OCStackResult registerDeviceInfo(
const OCDeviceInfo deviceInfo);
virtual OCStackResult registerPlatformInfo(
const OCPlatformInfo PlatformInfo);
virtual OCStackResult registerResourceWithHost(
OCResourceHandle& resourceHandle,
std::string& resourceHOST,
......
......@@ -202,6 +202,8 @@ namespace OC
typedef std::function<void(const OCRepresentation&)> FindDeviceCallback;
typedef std::function<void(const OCRepresentation&)> FindPlatformCallback;
typedef std::function<OCEntityHandlerResult(
const std::shared_ptr<OCResourceRequest>)> EntityHandler;
......
......@@ -143,6 +143,25 @@ namespace OC
OCConnectivityType connectivityType, FindDeviceCallback deviceInfoHandler,
QualityOfService QoS);
/**
* API for Platform Discovery
*
*
* @param host - Host IP Address. If null or empty, Multicast is performed.
* @param platformURI - Uri containing address to the virtual platform in C Stack
("/oic/p")